-1

For example, wanting a sum of 3 into 4 spaces would be:

3 0 0 0, 
0 3 0 0,
0 0 3 0,
0 0 0 3,
0 1 1 1,
1 0 1 1,
1 1 0 1,
1 1 1 0,
2 1 0 0,
... 

or sum of 3 into 2 spaces would be:

2 1
1 2
0 3
3 0

2 Answers2

4

The sequences you are looking for are called compositions.

Finding a composition of a number n is equivalent to selecting indices in an interval from 0 to n. You recover the composition by getting the distance between consecutive selected indices.

Example

Given the number n = 3, we want a composition of length 4.

The first two indices must be 0 and 3 since this is our range. We then select three more indices in the interval [0, 1, 2, 3] to produce exactly 4 gaps.

[0, 1, 2, 3]
 ^     ^  ^
       ^  ^

We thus selected 0, 2, 2, 3, 3. We recover the composition by getting the distance between consecutive indices. That is [2, 0, 1, 0].

This corresponds to taking a combination with replacement of numbers from 0 to 3. We can thus use itertools.combinations_with_replacement and translate each such combination into the corresponding composition.

Code

def compositions(sum_, n):
    for indices in combinations_with_replacement(range(sum_ + 1), n - 1):
        yield [b - a for a, b in zip([0, *indices], [*indices, sum_])]

print(*compositions(3, 4))

Output

[0, 0, 0, 3]
[0, 0, 1, 2]
[0, 0, 2, 1]
[0, 0, 3, 0]
[0, 1, 0, 2]
[0, 1, 1, 1]
[0, 1, 2, 0]
[0, 2, 0, 1]
[0, 2, 1, 0]
[0, 3, 0, 0]
[1, 0, 0, 2]
[1, 0, 1, 1]
[1, 0, 2, 0]
[1, 1, 0, 1]
[1, 1, 1, 0]
[1, 2, 0, 0]
[2, 0, 0, 1]
[2, 0, 1, 0]
[2, 1, 0, 0]
[3, 0, 0, 0]
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
1

Using itertools.product and filter create all the possibilities and then filter the ones whose sum is 3

from itertools import product

lst = [0, 1, 2, 3]
print(list(filter(lambda x: sum(x) == 3, product(lst, repeat = 4))))
print(list(filter(lambda x: sum(x) == 3, product(lst, repeat = 2))))
vash_the_stampede
  • 4,590
  • 1
  • 8
  • 20