]> gitweb.factorcode.org Git - factor.git/commitdiff
math.combinatorics: adding combinations-with-replacement
authorJohn Benediktsson <mrjbq7@gmail.com>
Fri, 28 Jan 2022 17:23:22 +0000 (09:23 -0800)
committerJohn Benediktsson <mrjbq7@gmail.com>
Fri, 28 Jan 2022 17:23:22 +0000 (09:23 -0800)
basis/math/combinatorics/combinatorics-tests.factor
basis/math/combinatorics/combinatorics.factor

index e18771e3332b2c9c77179fd24c8532ac92860638..3111d51bbd138dcbe7377eca0a7c7004a0ac1507 100644 (file)
@@ -52,6 +52,8 @@ math.combinatorics.private tools.test sequences sets ;
 { "ABC" "ACB" "BAC" "BCA" "CAB" "CBA" "ABC" }
 [ "ABC" 6 [ dup dup clone-like next-permutation ] times ] unit-test
 
+{ { "AA" "AB" "AC" "BB" "BC" "CC" } } [ "ABC" 2 all-combinations-with-replacement ] unit-test
+
 { { 0 1 2 } } [ 0 3 5 combination-indices ] unit-test
 { { 2 3 4 } } [ 9 3 5 combination-indices ] unit-test
 
index f4e9d5f2d340d379fda0821f24bef7ab7362cbae..d4023fa82af0d44dd8cc3542dcffa79a58ca5965 100644 (file)
@@ -184,6 +184,45 @@ PRIVATE>
 
 <PRIVATE
 
+:: next-combination-with-replacement ( seq n -- seq )
+    seq n 1 - '[ _ = not ] find-last drop :> i
+    seq i tail-slice i seq nth 1 + '[ drop _ ] map! drop
+    seq ; inline
+
+:: combinations-with-replacement-quot ( seq k quot -- seq quot' )
+    seq length :> n
+    k 1 - n + factorial k factorial / n 1 - factorial / <iota>
+    k 0 <array> seq quot n
+    '[ drop _ [ _ nths-unsafe @ ] keep _ next-combination-with-replacement drop ] ; inline
+
+PRIVATE>
+
+: each-combination-with-replacement ( ... seq k quot: ( ... elt -- ... ) -- ... )
+    combinations-with-replacement-quot each ; inline
+
+: map-combinations-with-replacement ( ... seq k quot: ( ... elt -- ... newelt ) -- ... newseq )
+    combinations-with-replacement-quot map ; inline
+
+: filter-combinations-with-replacement ( ... seq k quot: ( ... elt -- ... ? ) -- ... newseq )
+    selector [ each-combination-with-replacement ] dip ; inline
+
+: map>assoc-combinations-with-replacement ( ... seq k quot: ( ... elt -- ... key value ) exemplar -- ... assoc )
+    [ combinations-with-replacement-quot ] dip map>assoc ; inline
+
+: all-combinations-with-replacement ( seq k -- seq' )
+    [ ] map-combinations-with-replacement ;
+
+: all-combinations-with-replacement? ( ... seq k quot: ( ... elt -- ... ? ) -- ... ? )
+    combinations-with-replacement-quot all? ; inline
+
+: find-combination-with-replacement ( ... seq k quot: ( ... elt -- ... ? ) -- ... elt/f )
+    [ f ] 3dip '[ nip _ keep swap ] combinations-with-replacement-quot find drop swap and ; inline
+
+: reduce-combinations-with-replacement ( ... seq k identity quot: ( ... prev elt -- ... next ) -- ... result )
+    -rotd each-combination-with-replacement ; inline
+
+<PRIVATE
+
 ! "Algorithm 515: Generation of a Vector from the Lexicographical Index"
 ! Buckles, B. P., and Lybanon, M. ACM
 ! Transactions on Mathematical Software, Vol. 3, No. 2, June 1977.