Is there a way to change this nested loop into a recursive loop?
I think this is one possible implementation:
def bounded_comb(max_at_index, n):
yield from _bounded_comb_rec(max_at_index, n, [0] * len(max_at_index), [])
def _bounded_comb_rec(max_at_index, n, counts, current):
# If we have enough elements finish
if len(current) >= n:
yield tuple(current)
else:
# For each index and max
for idx, m in enumerate(max_at_index):
# If the max has not been reached
if m > counts[idx]:
# Add the index
counts[idx] += 1
current.append(idx)
# Produce all combinations
yield from _bounded_comb_rec(max_at_index, n, counts, current)
# Undo add the index
current.pop()
counts[idx] -= 1
# Test
max_at_index = [0, 2, 1, 3]
n = 4
print(*bounded_comb(max_at_index, n), sep='\n')
Output:
(1, 1, 2, 3)
(1, 1, 3, 2)
(1, 1, 3, 3)
(1, 2, 1, 3)
(1, 2, 3, 1)
(1, 2, 3, 3)
(1, 3, 1, 2)
(1, 3, 1, 3)
(1, 3, 2, 1)
(1, 3, 2, 3)
(1, 3, 3, 1)
(1, 3, 3, 2)
(1, 3, 3, 3)
(2, 1, 1, 3)
(2, 1, 3, 1)
(2, 1, 3, 3)
(2, 3, 1, 1)
(2, 3, 1, 3)
(2, 3, 3, 1)
(2, 3, 3, 3)
(3, 1, 1, 2)
(3, 1, 1, 3)
(3, 1, 2, 1)
(3, 1, 2, 3)
(3, 1, 3, 1)
(3, 1, 3, 2)
(3, 1, 3, 3)
(3, 2, 1, 1)
(3, 2, 1, 3)
(3, 2, 3, 1)
(3, 2, 3, 3)
(3, 3, 1, 1)
(3, 3, 1, 2)
(3, 3, 1, 3)
(3, 3, 2, 1)
(3, 3, 2, 3)
(3, 3, 3, 1)
(3, 3, 3, 2)