Okay, here's the problem I have. I'd like to do something like this:
V(n,k) generates all n-sized permutations in which each permutations contains all digits from 0 to k-1 in lexicographic order.
V(2,2) = { (0,1), (1,0) }
V(3,2) = { (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0) }
V(4,3) = { (0,0,1,2), (0,0,2,1), (0,1,0,2), (0,1,1,2), (0,1,2,0), ..., (2,2,1,0) }
Additional explanations For V(4,3) case, let's look at the sequence:
0012 -> 3 unique digits. Histogram: [2,1,1]
0021 -> 3 unique digits. Histogram: [2,1,1]
0102 -> 3 unique digits. Histogram: [2,1,1]
0112 -> 3 unique digits. Histogram: [1,2,1]
0120 -> 3 unique digits. Histogram: [2,1,1]
0121 -> 3 unique digits. Histogram: [1,2,1]
.....
2210 -> 3 unique digits. Histogram: [1,1,2]
As you can see, they all have k-amount of digits with different frequency. In addition, they are in lexicographic order.
The Code
The problem I have now is avoiding generating permutations where a number is missing. My input test was n=4 and k=3. So far, I do have this code, which correctly generates up to (0,2,0,1).
#@cli rep_rde_compsel_permutations: total_selection,number_of_item,_axis={x|y|z} : number_of_item_group,total_selection,_axis={x|y|z}
#@cli : Generates all possible permutations in which at least 1 item from each item group is select given N size.
#@cli : Author : Reptorian.
#@cli : Default values: '_axis=x'
+rep_rde_compsel_permutations:
skip ${3=x}
check isint($1,1)&&isint($2,1)&&inrange(('$3')[0],_'x',_'z',1,1)
number_of_item_groups,total_selection:=sort([${1-2}])
cutoff_point={$total_selection-$number_of_item_groups}
axis,length:=${-_rep_rde_lib_sterling_number_of_second_kind};[_'$3'-_'x',fact($number_of_item_groups)*sterling_number_of_second_kind($total_selection,$number_of_item_groups)]
{V=[1,1,1];V[$axis]=$length;V},$total_selection,>"begin(
const n_ig=$number_of_item_groups;
const dec_n_ig=n_ig-1;
const last_indice=s-1;
result=expr('x>$cutoff_point?x-$cutoff_point',s);
counts=histogram(result,n_ig,0,n_ig);
list_of_misses=vector(#n_ig);
min_rp=last_indice;
started=0;
);
started?(
missings=0;last_missing=-1;swapped=0;
t_counts=counts;
if(x==5,print(result));
result[last_indice-1,2]!=[0,1]?(
for(rp=last_indice,rp>=0,--rp,
last_v=result[rp];
current_v=(last_v+1)%n_ig;
is_current_missing=0;
if(!--t_counts[last_v]&&rp,
is_current_missing=1;
++missings;
last_missing=last_v;
);
--counts[last_v];
++counts[result[rp]=current_v];
if(is_current_missing&&missings==1,
continue();
);
if(last_v<dec_n_ig,
break();
);
);
if(missings&&result[rp]!=last_missing;,
--counts[result[last_indice]];
++counts[result[last_indice]=last_missing];
);
):(
swap(result[last_indice-1],result[last_indice]);
);
):(
started=1;
);
result;"
_rep_rde_lib_sterling_number_of_second_kind:
u "sterling_number_of_second_kind(_a,_b)=(
ref(vector(##_a-_b+1,1),_arr);
_max_q=_a-_b;
_i_max_q=_max_q+1;
for(_p=2,_p<=_b,++_p,
for(_q=1,_q<_i_max_q,++_q,
_arr[_q]+=_p*_arr[_q-1];
);
);
_res=_arr[_max_q];
unref(_arr);
_res;
);"
I know why it happens. (0,2,0,1). At the last indice, it becomes 2, and then second last indice becomes 1. So, it skips (0,2,1,0). (0,2,1,2) is generated next after (0,2,0,1).