Skip to content

Commit 5640f33

Browse files
committed
feat(list): add list:permutations and remove list:combinations, combinationsWithReplacement
1 parent 115fe68 commit 5640f33

2 files changed

Lines changed: 72 additions & 40 deletions

File tree

List.ark

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,7 @@
832832
(set _i (+ 1 _i)) })
833833
_output }))
834834

835-
# @brief Compute permutations of length _r from a given list
835+
# @brief Compute combinations of length _r from a given list
836836
# @details The original list is not modified.
837837
# @param _L list to get values from
838838
# @param _r number of elements per permutation
@@ -873,24 +873,7 @@
873873
(set _continue false)) }
874874
(set _continue false)) }) }) }) }))
875875

876-
# @brief Compute permutations of length _r from a given list
877-
# @details The original list is not modified.
878-
# @param _L list to get values from
879-
# @param _r number of elements per permutation
880-
# @param _f function to call on each permutation. It can return list:stopIteration to stop iteration early
881-
# @deprecated Use list:combinations. Will be removed in ArkScript 4.5.0
882-
# =begin
883-
# (let data [0 1 2 3])
884-
# (list:permutations data 3 (fun (perm) (print perm)))
885-
# # [0 1 2]
886-
# # [0 1 3]
887-
# # [0 2 3]
888-
# # [1 2 3]
889-
# =end
890-
# @author https://github.com/SuperFola
891-
(let permutations combinations)
892-
893-
# @brief Compute permutations of length _r from a given list, allowing individual elements to be repeated more than once
876+
# @brief Compute combinations of length _r from a given list, allowing individual elements to be repeated more than once
894877
# @details The original list is not modified.
895878
# @param _L list to get values from
896879
# @param _r number of elements per permutation
@@ -933,21 +916,53 @@
933916
(set _continue false)) }
934917
(set _continue false)) }) }) }) }))
935918

936-
# @brief Compute permutations of length _r from a given list, allowing individual elements to be repeated more than once
919+
# @brief Compute permutations of length _r from a given list
937920
# @details The original list is not modified.
938921
# @param _L list to get values from
939922
# @param _r number of elements per permutation
940923
# @param _f function to call on each permutation. It can return list:stopIteration to stop iteration early
941-
# @deprecated Use list:combinationsWithReplacement. Will be removed in ArkScript 4.5.0
942924
# =begin
943-
# (let data [0 1 2])
944-
# (list:permutationsWithReplacement data 2 (fun (perm) (print perm)))
945-
# # [0 0]
946-
# # [0 1]
947-
# # [0 2]
948-
# # [1 1]
949-
# # [1 2]
950-
# # [2 2]
925+
# (let data [0 1 2 3])
926+
# (mut out [])
927+
# (list:permutations data 3 (fun (perm) (append! out perm)))
928+
# (print out) # length: 24
929+
# # [[0 1 2] [0 1 3] [0 2 1] [0 2 3] [0 3 1] [0 3 2] [1 0 2] [1 0 3] [1 2 0] [1 2 3] [1 3 0] [1 3 2]
930+
# # [2 0 1] [2 0 3] [2 1 0] [2 1 3] [2 3 0] [2 3 1] [3 0 1] [3 0 2] [3 1 0] [3 1 2] [3 2 0] [3 2 1]]
951931
# =end
952932
# @author https://github.com/SuperFola
953-
(let permutationsWithReplacement combinationsWithReplacement)
933+
(let permutations (fun ((ref _L) _r _f) {
934+
(let _len (len _L))
935+
(if (and (<= _r _len) (> _r 0) (> _len 0))
936+
{
937+
(let _ind_first_r (iota 0 _r))
938+
(mut _indices (iota 0 _len))
939+
(mut _cycles (iterate _len (fun (x) (- x 1)) _r))
940+
(if (!= stopIteration (_f (select _L _ind_first_r)))
941+
{
942+
(mut _continue true)
943+
(let _reversed_indices (reverse _ind_first_r))
944+
(while _continue {
945+
(if
946+
(not (forEach
947+
_reversed_indices
948+
(fun (_i) {
949+
(@= _cycles _i (- (@ _cycles _i) 1))
950+
(if (= 0 (@ _cycles _i))
951+
{
952+
(let _at_i (@ _indices _i))
953+
(mut _k _i)
954+
(while (< _k _len) {
955+
(if (< (+ 1 _k) _len)
956+
(@= _indices _k (@ _indices (+ 1 _k))))
957+
(set _k (+ 1 _k)) })
958+
(@= _indices -1 _at_i)
959+
(@= _cycles _i (- _len _i)) }
960+
{
961+
(let _j (* -1 (@ _cycles _i)))
962+
(let _ind_j (@ _indices _j))
963+
(@= _indices _j (@ _indices _i))
964+
(@= _indices _i _ind_j)
965+
(if (= stopIteration (_f (select _L (select _indices _ind_first_r))))
966+
(set _continue false))
967+
stopIteration }) })))
968+
(set _continue false)) }) }) }) }))

tests/list-tests.ark

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -233,32 +233,49 @@
233233
(test:eq (list:select [1 2 3] [0]) [1])
234234
(test:eq (list:select [1 2 3] [0 4]) [1]) })
235235

236-
(test:case "permutations" {
236+
(test:case "combinations" {
237237
(mut perms [])
238-
(list:permutations "ABCD" 2 (fun (data) (append! perms data)))
238+
(list:combinations "ABCD" 2 (fun (data) (append! perms data)))
239239
(test:eq perms [["A" "B"] ["A" "C"] ["A" "D"] ["B" "C"] ["B" "D"] ["C" "D"]])
240240

241241
(set perms [])
242-
(list:permutations [0 1 2 3] 3 (fun (data) (append! perms data)))
242+
(list:combinations [0 1 2 3] 3 (fun (data) (append! perms data)))
243243
(test:eq perms [[0 1 2] [0 1 3] [0 2 3] [1 2 3]])
244244

245245
(set perms [])
246-
(list:permutations [0 1 2 3] 5 (fun (data) (append! perms data)))
246+
(list:combinations [0 1 2 3] 5 (fun (data) (append! perms data)))
247247
(test:eq perms [])
248248

249249
(set perms [])
250-
(list:permutations [] 0 (fun (data) (append! perms data)))
250+
(list:combinations [] 0 (fun (data) (append! perms data)))
251251
(test:eq perms []) })
252252

253-
(test:case "permutationsWithReplacement" {
253+
(test:case "combinationsWithReplacement" {
254254
(mut perms [])
255-
(list:permutationsWithReplacement "ABC" 2 (fun (data) (append! perms data)))
255+
(list:combinationsWithReplacement "ABC" 2 (fun (data) (append! perms data)))
256256
(test:eq perms [["A" "A"] ["A" "B"] ["A" "C"] ["B" "B"] ["B" "C"] ["C" "C"]])
257257

258258
(set perms [])
259-
(list:permutationsWithReplacement "ABC" 0 (fun (data) (append! perms data)))
259+
(list:combinationsWithReplacement "ABC" 0 (fun (data) (append! perms data)))
260260
(test:eq perms [])
261261

262262
(set perms [])
263-
(list:permutationsWithReplacement "" 2 (fun (data) (append! perms data)))
264-
(test:eq perms []) }) })
263+
(list:combinationsWithReplacement "" 2 (fun (data) (append! perms data)))
264+
(test:eq perms []) })
265+
266+
(test:case "permutations" {
267+
(mut perms [])
268+
(list:permutations "ABCD" 2 (fun (data) (append! perms data)))
269+
(test:eq perms [["A" "B"] ["A" "C"] ["A" "D"] ["B" "A"] ["B" "C"] ["B" "D"] ["C" "A"] ["C" "B"] ["C" "D"] ["D" "A"] ["D" "B"] ["D" "C"]])
270+
271+
(set perms [])
272+
(list:permutations [0 1 2 3] 3 (fun (data) (append! perms data)))
273+
(test:eq perms [[0 1 2] [0 1 3] [0 2 1] [0 2 3] [0 3 1] [0 3 2] [1 0 2] [1 0 3] [1 2 0] [1 2 3] [1 3 0] [1 3 2] [2 0 1] [2 0 3] [2 1 0] [2 1 3] [2 3 0] [2 3 1] [3 0 1] [3 0 2] [3 1 0] [3 1 2] [3 2 0] [3 2 1]])
274+
275+
(set perms [])
276+
(list:permutations [0 1 2 3] 5 (fun (data) (append! perms data)))
277+
(test:eq perms [])
278+
279+
(set perms [])
280+
(list:permutations [] 0 (fun (data) (append! perms data)))
281+
(test:eq perms []) }) })

0 commit comments

Comments
 (0)