52 lines
1.4 KiB
Factor
52 lines
1.4 KiB
Factor
! Copyright (c) 2007, 2008 Slava Pestov, Doug Coleman, Aaron Schaefer.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
USING: assocs kernel math math.order math.ranges mirrors
|
|
namespaces sequences sequences.lib sorting ;
|
|
IN: math.combinatorics
|
|
|
|
<PRIVATE
|
|
|
|
: possible? ( n m -- ? )
|
|
0 rot between? ; inline
|
|
|
|
: twiddle ( n k -- n k )
|
|
2dup - dupd > [ dupd - ] when ; inline
|
|
|
|
! See this article for explanation of the factoradic-based permutation methodology:
|
|
! http://msdn2.microsoft.com/en-us/library/aa302371.aspx
|
|
|
|
: factoradic ( n -- factoradic )
|
|
0 [ over 0 > ] [ 1+ [ /mod ] keep swap ] [ ] produce reverse 2nip ;
|
|
|
|
: (>permutation) ( seq n -- seq )
|
|
[ [ dupd >= [ 1+ ] when ] curry map ] keep prefix ;
|
|
|
|
: >permutation ( factoradic -- permutation )
|
|
reverse 1 cut [ (>permutation) ] each ;
|
|
|
|
: permutation-indices ( n seq -- permutation )
|
|
length [ factoradic ] dip 0 pad-left >permutation ;
|
|
|
|
PRIVATE>
|
|
|
|
: factorial ( n -- n! )
|
|
1 [ 1+ * ] reduce ;
|
|
|
|
: nPk ( n k -- nPk )
|
|
2dup possible? [ dupd - [a,b) product ] [ 2drop 0 ] if ;
|
|
|
|
: nCk ( n k -- nCk )
|
|
twiddle [ nPk ] keep factorial / ;
|
|
|
|
: permutation ( n seq -- seq )
|
|
tuck permutation-indices nths ;
|
|
|
|
: all-permutations ( seq -- seq )
|
|
[
|
|
[ length factorial ] keep [ permutation , ] curry each
|
|
] { } make ;
|
|
|
|
: inverse-permutation ( seq -- permutation )
|
|
<enum> >alist sort-values keys ;
|
|
|