Skip to content

Commit f10fcd9

Browse files
committed
feat(list): ARK-315, adding list:permutations_with_replacement
1 parent 78d562d commit f10fcd9

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

List.ark

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
# (list:fill 4 nil) # [nil nil nil nil]
5858
# =end
5959
# @author https://github.com/SuperFola
60-
(let fill (fun (_val _count) (builtin__list:fill _val _count)))
60+
(let fill (fun (_count _val) (builtin__list:fill _count _val)))
6161

6262
# @brief Function to call the `len` operator on a list
6363
# @param _L list to get the size of
@@ -843,3 +843,44 @@
843843
(if (= stopIteration (_f (select _L _indices)))
844844
(set _continue false)) }
845845
(set _continue false)) }) }) }) }))
846+
847+
# @brief Compute permutations of length _r from a given list, allowing individual elements to be repeated more than once
848+
# @details The original list is not modified.
849+
# @param _L list to get values from
850+
# @param _r number of elements per permutation
851+
# @param _f function to call on each permutation. It can return list:stopIteration to stop iteration early
852+
# =begin
853+
# (let data [0 1 2])
854+
# (list:permutations_with_replacement data 2 (fun (perm) (print perm)))
855+
# # [0 0]
856+
# # [0 1]
857+
# # [0 2]
858+
# # [1 1]
859+
# # [1 2]
860+
# # [2 2]
861+
# =end
862+
# @author https://github.com/SuperFola
863+
(let permutations_with_replacement (fun ((ref _L) _r _f) {
864+
(let _len (len _L))
865+
(if (and (!= 0 _len) (> _r 0))
866+
{
867+
(mut _indices (fill _r 0))
868+
(if (!= stopIteration (_f (select _L _indices)))
869+
{
870+
(mut _continue true)
871+
(let _reversed_range (iterate (- _r 1) (fun (_x) (- _x 1)) _r))
872+
(while _continue {
873+
(mut _i nil)
874+
(if
875+
(forEach _reversed_range (fun (_val) {
876+
(set _i _val)
877+
(if (!= (@ _indices _i) (- _len 1)) stopIteration) }))
878+
{
879+
(mut _j _i)
880+
(let _val (+ 1 (@ _indices _i)))
881+
(while (< _j _r) {
882+
(@= _indices _j _val)
883+
(set _j (+ 1 _j)) })
884+
(if (= stopIteration (_f (select _L _indices)))
885+
(set _continue false)) }
886+
(set _continue false)) }) }) }) }))

tests/list-tests.ark

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,4 +239,17 @@
239239

240240
(set perms [])
241241
(list:permutations [] 0 (fun (data) (append! perms data)))
242+
(test:eq perms []) })
243+
244+
(test:case "permutations_with_replacement" {
245+
(mut perms [])
246+
(list:permutations_with_replacement "ABC" 2 (fun (data) (append! perms data)))
247+
(test:eq perms [["A" "A"] ["A" "B"] ["A" "C"] ["B" "B"] ["B" "C"] ["C" "C"]])
248+
249+
(set perms [])
250+
(list:permutations_with_replacement "ABC" 0 (fun (data) (append! perms data)))
251+
(test:eq perms [])
252+
253+
(set perms [])
254+
(list:permutations_with_replacement "" 2 (fun (data) (append! perms data)))
242255
(test:eq perms []) }) })

0 commit comments

Comments
 (0)