Coin Change Problem Enumeration Using N Coins And Each Denomination
MATL, 22 bytes
Z^!S!Xu!tsi=Z)"1G@m?@!
Input order is: array of denominations, number of coins taken (n
), desired sum (y
).
Each combination is displayed on a different line. Empty output is displayed as an empty string (so nothing).
Try it online!
The code runs out of memory in the online compiler for the example in the challenge, but works offline with a standard, reasonably modern computer:
>> matl
> Z^!S!Xu!tsi=Z)"1G@m?@!
>
> [1 2 3]
> 15
> 36
1 1 1 1 2 3 3 3 3 3 3 3 3 3 3
1 1 1 2 2 2 3 3 3 3 3 3 3 3 3
1 1 2 2 2 2 2 3 3 3 3 3 3 3 3
1 2 2 2 2 2 2 2 3 3 3 3 3 3 3
Explanation
Z^ % Implicitly input array of denomminations and number of coins n. Compute
% Cartesian power. This gives 2D array with each "combination"
% on a different row
!S! % Sort each row
Xu % Deduplicate rows
! % Transpose: rows become columns. Call this array A
ts % Push a copy, compute sum of each column
i % Input y (desired sum)
= % Logical array that contains true if the "combination" has the desired sum
Z) % Keep only those columns in array A
" % For each column
1G % Push array of denominations again
@ % Push current column
m % Is each denomination present in the column?
? % If so
@! % Push current column again. Transpose into a row
% End if
% End for
% Implicitly display stack contents
Python 3, 120 106 bytes
from itertools import*
lambda d,t,l:[i+d for i in combinations_with_replacement(d,l-len(d))if sum(i+d)==t]
An anonymous function that takes input of a tuple of denominations of the form (x_1, x_2, x_3 ... , x_k)
, a target value, and a number of coins via argument, and returns a list of tuples of the form [(solution_1), (solution_2), (solution_3), ... (solution_k)]
.
How it works
Itertools
's combinations_with_replacement
function is used to generate all l-len(d)
combinations, with replacement, of the denominations. By appending d
to each of these combinations, it is guaranteed that each denomination appears at least once, and that the new combination has length l
. If the elements of a combination sum to t
, the combination is added to the return list as a tuple.
Try it on Ideone
An alternative method for 108 bytes
from itertools import*
lambda d,t,l:set(tuple(sorted(i+d))for i in product(d,repeat=l-len(d))if sum(i+d)==t)
An anonymous function that takes input of a tuple of denominations of the form (x_1, x_2, x_3 ... , x_k)
, a target value, and a number of coins via argument, and returns a set of tuples of the form {(solution_1), (solution_2), (solution_3), ... (solution_k)}
.
How it works (other version)
This uses the product
function from itertools
to generate all l-len(d)
arrangements of the denominations. By appending d
to each of these combinations, it is guaranteed that each denomination appears at least once, and that the new combination has length l
. If the elements of a combination sum to t
, the combination is sorted, converted from a list to a tuple, and added to the return tuples. Finally, calling set
removes any duplicates.
Try it on Ideone (other version)
05AB1E, 20 bytes
g-¹sã€{Ùvy¹«DO³Qiˆ}¯
Input is in the order: list of values
, nr of coins
, sum to reach
.
Explanation in short
- Get all permutations of the coin list of length:
final length - length of unique coin list
- Add the list of unique coins to these lists.
- If the sum equals the sought after sum, save the list
- Output all saved lists
Try it online
The online compiler can't handle large number of coins.