 
 C: <combo> combo
 
+: choose ( combo -- nCk )
+    [ seq>> length ] [ k>> ] bi nCk ;
+
 : largest-value ( a b x -- v )
     #! TODO: use a binary search instead of find-last
     [ [0,b) ] 2dip '[ _ nCk _ <= ] find-last nip ;

    [ permutation-indices ] keep nths ;

: all-permutations ( seq -- seq )
    [ length factorial ] keep '[ _ permutation ] map ;

: each-permutation ( seq quot -- )
    [ [ length factorial ] keep ] dip

    x v b nCk -                   ! x'
    v ;                           ! v == a'

: dual-index ( m combo -- m' )
    choose 1 - swap - ;

: initial-values ( combo m -- n k m )
    [ [ seq>> length ] [ k>> ] bi ] dip ;

: combinadic ( combo m -- combinadic )
    initial-values [ over 0 > ] [ next-values ] produce
    [ 3drop ] dip ;

: combination-indices ( m combo -- seq )
    [ tuck dual-index combinadic ] keep
    seq>> length 1 - swap [ - ] with map ;

: apply-combination ( m combo -- seq )
    [ combination-indices ] keep seq>> nths ;

PRIVATE>

