math.combinatorics: implementing "next-permutation".

db4
John Benediktsson 2012-03-02 09:54:11 -08:00
parent 9ee314b906
commit 8d56193edd
3 changed files with 33 additions and 0 deletions

View File

@ -103,6 +103,12 @@ HELP: >permutation
{ $notes "For clarification, the following two statements are equivalent:" { $code "10 factoradic >permutation" "{ 1 2 0 0 } >permutation" } }
{ $examples { $example "USING: math.combinatorics.private prettyprint ;" "{ 0 0 0 0 } >permutation ." "{ 0 1 2 3 }" } } ;
HELP: next-permutation
{ $values { "seq" sequence } { "seq" sequence } }
{ $description "Rearranges the elements in " { $snippet "seq" } " into the lexicographically next greater permutation of elements" }
{ $notes "Performs an in-place modification of " { $snippet "seq" } "." }
{ $examples { $example "USING: math.combinatorics prettyprint ;" "\"ABC\" next-permutation ." "\"ACB\"" } } ;
HELP: all-subsets
{ $values { "seq" sequence } { "subsets" sequence } }
{ $description

View File

@ -44,6 +44,12 @@ IN: math.combinatorics.tests
[ { 2 1 0 } ] [ { "c" "b" "a" } inverse-permutation ] unit-test
[ { 3 0 2 1 } ] [ { 12 45 34 2 } inverse-permutation ] unit-test
[ "" ] [ "" next-permutation ] unit-test
[ "1" ] [ "1" next-permutation ] unit-test
[ "21" ] [ "12" next-permutation ] unit-test
[ "8344112666" ] [ "8342666411" next-permutation ] unit-test
[ "ABC" "ACB" "BAC" "BCA" "CAB" "CBA" "ABC" ]
[ "ABC" 6 [ dup >string next-permutation ] times ] unit-test
[ 2598960 ] [ 52 iota 5 <combo> choose ] unit-test

View File

@ -61,6 +61,27 @@ PRIVATE>
: inverse-permutation ( seq -- permutation )
<enum> sort-values keys ;
<PRIVATE
: cut-point ( seq -- n )
[ last ] keep [ [ > ] keep swap ] find-last drop nip ;
: greater-from-last ( n seq -- i )
[ nip ] [ nth ] 2bi [ > ] curry find-last drop ;
: reverse-tail! ( n seq -- seq )
[ swap 1 + tail-slice reverse! drop ] keep ;
: (next-permutation) ( seq -- seq )
dup cut-point [
swap [ greater-from-last ] 2keep
[ exchange ] [ reverse-tail! nip ] 3bi
] [ reverse! ] if* ;
PRIVATE>
: next-permutation ( seq -- seq )
dup [ ] [ drop (next-permutation) ] if-empty ;
! Combinadic-based combination methodology