1 ! Copyright (c) 2007, 2008 Slava Pestov, Doug Coleman, Aaron Schaefer.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: assocs kernel math math.order math.ranges mirrors
4 namespaces sequences sorting fry ;
9 : possible? ( n m -- ? )
10 0 rot between? ; inline
12 : twiddle ( n k -- n k )
13 2dup - dupd > [ dupd - ] when ; inline
15 ! See this article for explanation of the factoradic-based permutation methodology:
16 ! http://msdn2.microsoft.com/en-us/library/aa302371.aspx
18 : factoradic ( n -- factoradic )
19 0 [ over 0 > ] [ 1+ [ /mod ] keep swap ] [ ] produce reverse 2nip ;
21 : (>permutation) ( seq n -- seq )
22 [ '[ _ dupd >= [ 1+ ] when ] map ] keep prefix ;
24 : >permutation ( factoradic -- permutation )
25 reverse 1 cut [ (>permutation) ] each ;
27 : permutation-indices ( n seq -- permutation )
28 length [ factoradic ] dip 0 pad-left >permutation ;
32 : factorial ( n -- n! )
36 2dup possible? [ dupd - [a,b) product ] [ 2drop 0 ] if ;
39 twiddle [ nPk ] keep factorial / ;
41 : permutation ( n seq -- seq )
42 [ permutation-indices ] keep nths ;
44 : all-permutations ( seq -- seq )
45 [ length factorial ] keep '[ _ permutation ] map ;
47 : each-permutation ( seq quot -- )
48 [ [ length factorial ] keep ] dip
49 '[ _ permutation @ ] each ; inline
51 : reduce-permutations ( seq initial quot -- result )
52 swapd each-permutation ; inline
54 : inverse-permutation ( seq -- permutation )
55 <enum> >alist sort-values keys ;