factor/basis/math/combinatorics/combinatorics.factor

56 lines
1.5 KiB
Factor
Raw Normal View History

! Copyright (c) 2007, 2008 Slava Pestov, Doug Coleman, Aaron Schaefer.
! See http://factorcode.org/license.txt for BSD license.
2008-04-26 12:03:41 -04:00
USING: assocs kernel math math.order math.ranges mirrors
2008-10-03 03:19:03 -04:00
namespaces sequences sorting fry ;
2007-09-20 18:09:08 -04:00
IN: math.combinatorics
<PRIVATE
2007-09-20 18:09:08 -04:00
: possible? ( n m -- ? )
0 rot between? ; inline
2007-09-20 18:09:08 -04:00
: twiddle ( n k -- n k )
2dup - dupd > [ dupd - ] when ; inline
2007-09-20 18:09:08 -04:00
! See this article for explanation of the factoradic-based permutation methodology:
2008-10-03 03:19:03 -04:00
! http://msdn2.microsoft.com/en-us/library/aa302371.aspx
2007-09-20 18:09:08 -04:00
: factoradic ( n -- factoradic )
0 [ over 0 > ] [ 1+ [ /mod ] keep swap ] [ ] produce reverse 2nip ;
: (>permutation) ( seq n -- seq )
2008-11-07 01:24:32 -05:00
[ '[ _ dupd >= [ 1+ ] when ] 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 ;
2007-09-20 18:09:08 -04:00
: nCk ( n k -- nCk )
twiddle [ nPk ] keep factorial / ;
: permutation ( n seq -- seq )
2008-10-03 03:19:03 -04:00
[ permutation-indices ] keep nths ;
2007-09-20 18:09:08 -04:00
: all-permutations ( seq -- seq )
2008-10-03 03:19:03 -04:00
[ length factorial ] keep '[ _ permutation ] map ;
: each-permutation ( seq quot -- )
[ [ length factorial ] keep ] dip
'[ _ permutation @ ] each ; inline
: reduce-permutations ( seq initial quot -- result )
swapd each-permutation ; inline
: inverse-permutation ( seq -- permutation )
2007-09-20 18:09:08 -04:00
<enum> >alist sort-values keys ;