JavaScript
x
11
11
1
N = 14
2
SIZE = 6
3
lst = range(N+1)
4
sum_n_combs = [
5
list(comb) for comb in it.combinations_with_replacement(lst, SIZE)
6
if sum(comb) == N
7
]
8
print(sum_n_combs)
9
10
output [[0, 0, 0, 0, 0, 14], [0, 0, 0, 0, 1, 13], [0, 0, 0, 0, 2, 12], [0, 0, 0, 0, 3, 11], [0, 0, 0, 0, 4, 10], [0, 0, 0, 0, 5, 9], [0, 0, 0, 0, 6, 8], [0, 0, 0, 0, 7, 7], [0, 0, 0, 1, 1, 12], [0, 0, 0, 1, 2, 11], [0, 0, 0, 1, 3, 10], [0, 0, 0, 1, 4, 9], [0, 0, 0, 1, 5, 8], [0, 0, 0, 1, 6, 7], [0, 0, 0, 2, 2, 10], [0, 0, 0, 2, 3, 9], [0, 0, 0, 2, 4, 8], [0, 0, 0, 2, 5, 7], [0, 0, 0, 2, 6, 6], [0, 0, 0, 3, 3, 8], [0, 0, 0, 3, 4, 7], [0, 0, 0, 3, 5, 6], [0, 0, 0, 4, 4, 6], [0, 0, 0, 4, 5, 5], [0, 0, 1, 1, 1, 11], [0, 0, 1, 1, 2, 10], [0, 0, 1, 1, 3, 9], [0, 0, 1, 1, 4, 8], [0, 0, 1, 1, 5, 7], [0, 0, 1, 1, 6, 6], [0, 0, 1, 2, 2, 9], [0, 0, 1, 2, 3, 8], [0, 0, 1, 2, 4, 7], [0, 0, 1, 2, 5, 6], [0, 0, 1, 3, 3, 7], [0, 0, 1, 3, 4, 6], [0, 0, 1, 3, 5, 5], [0, 0, 1, 4, 4, 5], [0, 0, 2, 2, 2, 8], [0, 0, 2, 2, 3, 7], [0, 0, 2, 2, 4, 6], [0, 0, 2, 2, 5, 5], [0, 0, 2, 3, 3, 6], [0, 0, 2, 3, 4, 5], [0, 0, 2, 4, 4, 4], [0, 0, 3, 3, 3, 5], [0, 0, 3, 3, 4, 4], [0, 1, 1, 1, 1, 10], [0, 1, 1, 1, 2, 9], [0, 1, 1, 1, 3, 8], [0, 1, 1, 1, 4, 7], [0, 1, 1, 1, 5, 6], [0, 1, 1, 2, 2, 8], [0, 1, 1, 2, 3, 7], [0, 1, 1, 2, 4, 6], [0, 1, 1, 2, 5, 5], [0, 1, 1, 3, 3, 6], [0, 1, 1, 3, 4, 5], [0, 1, 1, 4, 4, 4], [0, 1, 2, 2, 2, 7], [0, 1, 2, 2, 3, 6], [0, 1, 2, 2, 4, 5], [0, 1, 2, 3, 3, 5], [0, 1, 2, 3, 4, 4], [0, 1, 3, 3, 3, 4], [0, 2, 2, 2, 2, 6], [0, 2, 2, 2, 3, 5], [0, 2, 2, 2, 4, 4], [0, 2, 2, 3, 3, 4], [0, 2, 3, 3, 3, 3], [1, 1, 1, 1, 1, 9], [1, 1, 1, 1, 2, 8], [1, 1, 1, 1, 3, 7], [1, 1, 1, 1, 4, 6], [1, 1, 1, 1, 5, 5], [1, 1, 1, 2, 2, 7], [1, 1, 1, 2, 3, 6], [1, 1, 1, 2, 4, 5], [1, 1, 1, 3, 3, 5], [1, 1, 1, 3, 4, 4], [1, 1, 2, 2, 2, 6], [1, 1, 2, 2, 3, 5], [1, 1, 2, 2, 4, 4], [1, 1, 2, 3, 3, 4], [1, 1, 3, 3, 3, 3], [1, 2, 2, 2, 2, 5], [1, 2, 2, 2, 3, 4], [1, 2, 2, 3, 3, 3], [2, 2, 2, 2, 2, 4], [2, 2, 2, 2, 3, 3]]
11
As “combinations with replacement” does, this function only produces the combination. I want permutation of each combination without repetition. For example
JavaScript
1
2
1
[[0, 0, 0, 0, 0, 14], [0, 0, 0, 0, 14, 0] [3, 2, 3, 2, 2, 2], [3, 3, 2, 2, 2]]
2
When I tried to do this by
JavaScript
1
4
1
ret=[]
2
for i in range(90):
3
ret.extend(it.permutations(sum_n_combs[i], SIZE))
4
Time complexity was exponential, and made repititions When I tested with one list sum_n_combs[0], which is [0, 0, 0, 0, 0, 14] produced 720 permutations when I only want 6 of them(14 at each different place).
How can I make permutation without repetition for each combination in an efficient way?
Advertisement
Answer
You could separate this in two steps:
- generate partitions of the targeted sum
- generate distinct permutations of each partition
Recursive generators will allow you to get the results efficiently without trial/error filtering and without storing everything in memory:
JavaScript
1
19
19
1
def partitions(N,size):
2
if size == 1 :
3
yield (N,) # base case, only 1 part
4
return
5
for a in range(N//size+1): # smaller part followed by
6
for p in partitions(N-a*size,size-1): # equal or larger ones
7
yield (a, *(n+a for n in p)) # recursing on delta only
8
9
def permuteDistinct(A):
10
if len(A) == 1:
11
yield tuple(A) # single value
12
return
13
used = set() # track starting value
14
for i,n in enumerate(A): # for each starting value
15
if n in used: continue # not yet used
16
used.add(n)
17
for p in permuteDistinct(A[:i]+A[i+1:]):
18
yield (n,*p) # starting value & rest
19
output:
JavaScript
1
3
1
N = 14
2
SIZE = 6
3
PARTITIONS…
JavaScript
1
29
29
1
for part in partitions(N,SIZE):
2
print(part)
3
4
(0, 0, 0, 0, 0, 14)
5
(0, 0, 0, 0, 1, 13)
6
(0, 0, 0, 0, 2, 12)
7
(0, 0, 0, 0, 3, 11)
8
(0, 0, 0, 0, 4, 10)
9
(0, 0, 0, 0, 5, 9)
10
(0, 0, 0, 0, 6, 8)
11
(0, 0, 0, 0, 7, 7)
12
(0, 0, 0, 1, 1, 12)
13
(0, 0, 0, 1, 2, 11)
14
(0, 0, 0, 1, 3, 10)
15
(0, 0, 0, 1, 4, 9)
16
(0, 0, 0, 1, 5, 8)
17
(0, 0, 0, 1, 6, 7)
18
(0, 0, 0, 2, 2, 10)
19
(0, 0, 0, 2, 3, 9)
20
(0, 0, 0, 2, 4, 8)
21
(0, 0, 0, 2, 5, 7)
22
(0, 0, 0, 2, 6, 6)
23
(0, 0, 0, 3, 3, 8)
24
(0, 0, 0, 3, 4, 7)
25
(0, 0, 0, 3, 5, 6)
26
(0, 0, 0, 4, 4, 6)
27
(0, 0, 0, 4, 5, 5)
28
29
PERMUTED PARTITIONS (DISTINCT):
JavaScript
1
24
24
1
for part in partitions(N,SIZE):
2
for permutedPart in permuteDistinct(part):
3
print(permutedPart)
4
5
(0, 0, 0, 0, 0, 14)
6
(0, 0, 0, 0, 14, 0)
7
(0, 0, 0, 14, 0, 0)
8
(0, 0, 14, 0, 0, 0)
9
(0, 14, 0, 0, 0, 0)
10
(14, 0, 0, 0, 0, 0)
11
(0, 0, 0, 0, 1, 13)
12
(0, 0, 0, 0, 13, 1)
13
(0, 0, 0, 1, 0, 13)
14
(0, 0, 0, 1, 13, 0)
15
(0, 0, 0, 13, 0, 1)
16
(0, 0, 0, 13, 1, 0)
17
(0, 0, 1, 0, 0, 13)
18
(0, 0, 1, 0, 13, 0)
19
(0, 0, 1, 13, 0, 0)
20
(0, 0, 13, 0, 0, 1)
21
(0, 0, 13, 0, 1, 0)
22
(0, 0, 13, 1, 0, 0)
23
24