The problem involves the fastest possible method to generate a list of combinations which repeats from all the possible combinations with repetition allowed. I know there needs to be a way to calculate n from gamma(n,r)=v given r and v in order to get the fastest possible approach, but it's probably not solvable, so to the realm of what we have now.
So, this means from a list of 3 items and maximum of 5 repetition, and rank, the list would look something like this:
Rank - Combinations
0 - 0,0,0,0,0
1 - 0,0,0,0,1
2 - 0,0,0,0,2
....
20 - 2,2,2,2,2
At the moment, my Python code to this problem:
import math
def calc_approximate_n(v,r):
return max(r,int((v*math.factorial(r)-r)**(1/r)))
NUMBER_OF_ITEMS=3
REPETITIONS=5
DECREMENT_REPETITIONS=REPETITIONS-1
NUMBER_OF_COMBS=math.comb(NUMBER_OF_ITEMS+REPETITIONS-1,REPETITIONS)
MAX_COMB_RANK=NUMBER_OF_COMBS-1
rank=7
rank %= NUMBER_OF_COMBS
Tc=NUMBER_OF_ITEMS-1
if rank==0:
print([0]*REPETITIONS)
elif rank==MAX_COMB_RANK:
print([Tc]*REPETITIONS)
elif rank<NUMBER_OF_ITEMS:
output_list=[0]*REPETITIONS
output_list[-1]=rank
print(output_list)
else:
output_list=[0]*REPETITIONS
while True:
Tn=calc_approximate_n(rank,Tc)
FTn=Tn-Tc+1
last_n=math.comb(Tn,Tc)
ncr_val=last_n
while ncr_val<rank:
Tn += 1
ncr_val=math.comb(Tn,Tc)
if ncr_val<=rank:
last_n=ncr_val
FTn += 1
rank -= last_n
Tc -= 1
insertion_pos=DECREMENT_REPETITIONS
for _ in range(FTn):
output_list[insertion_pos] += 1
insertion_pos -= 1
if rank==0 or Tc==0:
break
print(output_list)
So, with 3 items and maximum repetition of 5 and rank 7, I get this combination => [0, 0, 1, 1, 2]
Now, with 5 items, and maximum repetition of 12 and rank 1700, I get this combination => [1, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4]