How do I create a generator that will return tuples of all combinations of positive integers, example for generating triplets.
JavaScript
x
11
11
1
(1, 1, 1)
2
(2, 1, 1)
3
(1, 2, 1)
4
(1, 1, 2)
5
(2, 2, 1)
6
(2, 1, 2)
7
(2, 2, 2)
8
(3, 2, 2)
9
(2, 3, 2)
10
# and so on...
11
Advertisement
Answer
This code uses a similar approach to Paul Hankin’s, but it’s more general since it will generate tuples of any desired width, not just 3.
JavaScript
1
20
20
1
from itertools import combinations, count
2
3
def compositions(num, width):
4
m = num - 1
5
first, last = (-1,), (m,)
6
for t in combinations(range(m), width - 1):
7
yield tuple(v - u for u, v in zip(first + t, t + last))
8
9
def ordered_compositions(width):
10
for n in count(width):
11
yield from compositions(n, width)
12
13
# test
14
15
width = 3
16
for i, t in enumerate(ordered_compositions(width), 1):
17
print(i, t)
18
if i > 30:
19
break
20
output
JavaScript
1
32
32
1
1 (1, 1, 1)
2
2 (1, 1, 2)
3
3 (1, 2, 1)
4
4 (2, 1, 1)
5
5 (1, 1, 3)
6
6 (1, 2, 2)
7
7 (1, 3, 1)
8
8 (2, 1, 2)
9
9 (2, 2, 1)
10
10 (3, 1, 1)
11
11 (1, 1, 4)
12
12 (1, 2, 3)
13
13 (1, 3, 2)
14
14 (1, 4, 1)
15
15 (2, 1, 3)
16
16 (2, 2, 2)
17
17 (2, 3, 1)
18
18 (3, 1, 2)
19
19 (3, 2, 1)
20
20 (4, 1, 1)
21
21 (1, 1, 5)
22
22 (1, 2, 4)
23
23 (1, 3, 3)
24
24 (1, 4, 2)
25
25 (1, 5, 1)
26
26 (2, 1, 4)
27
27 (2, 2, 3)
28
28 (2, 3, 2)
29
29 (2, 4, 1)
30
30 (3, 1, 3)
31
31 (3, 2, 2)
32
The algorithm for compositions
was derived from the technique used for counting the number of compositions explained in the Wikipedia article on compositions. This is essentially a variation of the well-known Stars and Bars technique.