I don't think using combinations()
will work here- the function returns combinations of the array you pass it, but does not create duplicates of any given element. You could get around this by using a variant combinations_with_replacement()
, but even then you'll end up with an excess of invalid combinations, and for lengthy lists the runtime would become intractable.
Instead, consider a recursive solution like the following.
def reps(target, nums):
res = []
for i, v in enumerate(nums):
if target - v > 0:
res += [[v] + l for l in reps(target-v, nums[i:])]
elif target - v == 0:
res += [[v]]
return res
Here I take a target sum and a list of numbers, and try subtracting out each number from the target. If the difference exactly equals 0, I add that last value to the list. If its great than zero, I keep attempting to add elements to the list by calling reps()
with the new target value, and a subset of the original numbers which prevents permutations of the same answer. I combine all these, prepend the previously chosen value from the list, and continue in this fashion until a list of all combinations has been built.
The result for your example target=5
and nums=[1,2,3]
-
[[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 1, 3], [1, 2, 2], [2, 3]]