From 5640f336fd9631b1b2bb61d0ebeea68dc0c1915f Mon Sep 17 00:00:00 2001 From: Lexy Plt Date: Fri, 13 Mar 2026 12:26:18 +0100 Subject: [PATCH 1/2] feat(list): add list:permutations and remove list:combinations, combinationsWithReplacement --- List.ark | 75 ++++++++++++++++++++++++++------------------ tests/list-tests.ark | 37 ++++++++++++++++------ 2 files changed, 72 insertions(+), 40 deletions(-) diff --git a/List.ark b/List.ark index 55b97f5..5c096d8 100644 --- a/List.ark +++ b/List.ark @@ -832,7 +832,7 @@ (set _i (+ 1 _i)) }) _output })) -# @brief Compute permutations of length _r from a given list +# @brief Compute combinations of length _r from a given list # @details The original list is not modified. # @param _L list to get values from # @param _r number of elements per permutation @@ -873,24 +873,7 @@ (set _continue false)) } (set _continue false)) }) }) }) })) -# @brief Compute permutations of length _r from a given list -# @details The original list is not modified. -# @param _L list to get values from -# @param _r number of elements per permutation -# @param _f function to call on each permutation. It can return list:stopIteration to stop iteration early -# @deprecated Use list:combinations. Will be removed in ArkScript 4.5.0 -# =begin -# (let data [0 1 2 3]) -# (list:permutations data 3 (fun (perm) (print perm))) -# # [0 1 2] -# # [0 1 3] -# # [0 2 3] -# # [1 2 3] -# =end -# @author https://github.com/SuperFola -(let permutations combinations) - -# @brief Compute permutations of length _r from a given list, allowing individual elements to be repeated more than once +# @brief Compute combinations of length _r from a given list, allowing individual elements to be repeated more than once # @details The original list is not modified. # @param _L list to get values from # @param _r number of elements per permutation @@ -933,21 +916,53 @@ (set _continue false)) } (set _continue false)) }) }) }) })) -# @brief Compute permutations of length _r from a given list, allowing individual elements to be repeated more than once +# @brief Compute permutations of length _r from a given list # @details The original list is not modified. # @param _L list to get values from # @param _r number of elements per permutation # @param _f function to call on each permutation. It can return list:stopIteration to stop iteration early -# @deprecated Use list:combinationsWithReplacement. Will be removed in ArkScript 4.5.0 # =begin -# (let data [0 1 2]) -# (list:permutationsWithReplacement data 2 (fun (perm) (print perm))) -# # [0 0] -# # [0 1] -# # [0 2] -# # [1 1] -# # [1 2] -# # [2 2] +# (let data [0 1 2 3]) +# (mut out []) +# (list:permutations data 3 (fun (perm) (append! out perm))) +# (print out) # length: 24 +# # [[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]] # =end # @author https://github.com/SuperFola -(let permutationsWithReplacement combinationsWithReplacement) +(let permutations (fun ((ref _L) _r _f) { + (let _len (len _L)) + (if (and (<= _r _len) (> _r 0) (> _len 0)) + { + (let _ind_first_r (iota 0 _r)) + (mut _indices (iota 0 _len)) + (mut _cycles (iterate _len (fun (x) (- x 1)) _r)) + (if (!= stopIteration (_f (select _L _ind_first_r))) + { + (mut _continue true) + (let _reversed_indices (reverse _ind_first_r)) + (while _continue { + (if + (not (forEach + _reversed_indices + (fun (_i) { + (@= _cycles _i (- (@ _cycles _i) 1)) + (if (= 0 (@ _cycles _i)) + { + (let _at_i (@ _indices _i)) + (mut _k _i) + (while (< _k _len) { + (if (< (+ 1 _k) _len) + (@= _indices _k (@ _indices (+ 1 _k)))) + (set _k (+ 1 _k)) }) + (@= _indices -1 _at_i) + (@= _cycles _i (- _len _i)) } + { + (let _j (* -1 (@ _cycles _i))) + (let _ind_j (@ _indices _j)) + (@= _indices _j (@ _indices _i)) + (@= _indices _i _ind_j) + (if (= stopIteration (_f (select _L (select _indices _ind_first_r)))) + (set _continue false)) + stopIteration }) }))) + (set _continue false)) }) }) }) })) diff --git a/tests/list-tests.ark b/tests/list-tests.ark index 2fda069..9993814 100644 --- a/tests/list-tests.ark +++ b/tests/list-tests.ark @@ -233,32 +233,49 @@ (test:eq (list:select [1 2 3] [0]) [1]) (test:eq (list:select [1 2 3] [0 4]) [1]) }) - (test:case "permutations" { + (test:case "combinations" { (mut perms []) - (list:permutations "ABCD" 2 (fun (data) (append! perms data))) + (list:combinations "ABCD" 2 (fun (data) (append! perms data))) (test:eq perms [["A" "B"] ["A" "C"] ["A" "D"] ["B" "C"] ["B" "D"] ["C" "D"]]) (set perms []) - (list:permutations [0 1 2 3] 3 (fun (data) (append! perms data))) + (list:combinations [0 1 2 3] 3 (fun (data) (append! perms data))) (test:eq perms [[0 1 2] [0 1 3] [0 2 3] [1 2 3]]) (set perms []) - (list:permutations [0 1 2 3] 5 (fun (data) (append! perms data))) + (list:combinations [0 1 2 3] 5 (fun (data) (append! perms data))) (test:eq perms []) (set perms []) - (list:permutations [] 0 (fun (data) (append! perms data))) + (list:combinations [] 0 (fun (data) (append! perms data))) (test:eq perms []) }) - (test:case "permutationsWithReplacement" { + (test:case "combinationsWithReplacement" { (mut perms []) - (list:permutationsWithReplacement "ABC" 2 (fun (data) (append! perms data))) + (list:combinationsWithReplacement "ABC" 2 (fun (data) (append! perms data))) (test:eq perms [["A" "A"] ["A" "B"] ["A" "C"] ["B" "B"] ["B" "C"] ["C" "C"]]) (set perms []) - (list:permutationsWithReplacement "ABC" 0 (fun (data) (append! perms data))) + (list:combinationsWithReplacement "ABC" 0 (fun (data) (append! perms data))) (test:eq perms []) (set perms []) - (list:permutationsWithReplacement "" 2 (fun (data) (append! perms data))) - (test:eq perms []) }) }) + (list:combinationsWithReplacement "" 2 (fun (data) (append! perms data))) + (test:eq perms []) }) + + (test:case "permutations" { + (mut perms []) + (list:permutations "ABCD" 2 (fun (data) (append! perms data))) + (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"]]) + + (set perms []) + (list:permutations [0 1 2 3] 3 (fun (data) (append! perms data))) + (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]]) + + (set perms []) + (list:permutations [0 1 2 3] 5 (fun (data) (append! perms data))) + (test:eq perms []) + + (set perms []) + (list:permutations [] 0 (fun (data) (append! perms data))) + (test:eq perms []) }) }) From 30b8846773f19c182636384dad34dbc34ea0e65e Mon Sep 17 00:00:00 2001 From: Lexy Plt Date: Fri, 13 Mar 2026 12:35:08 +0100 Subject: [PATCH 2/2] chore: format list.ark --- List.ark | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/List.ark b/List.ark index 5c096d8..a16dfdd 100644 --- a/List.ark +++ b/List.ark @@ -669,9 +669,13 @@ (mut _output []) (mut _last _start) - (while (if (> _step 0) (< _last _end) (> _last _end)) { - (append! _output _last) - (set _last (+ _last _step)) }) + (while + (if (> _step 0) + (< _last _end) + (> _last _end)) + { + (append! _output _last) + (set _last (+ _last _step)) }) _output })) @@ -943,26 +947,26 @@ (let _reversed_indices (reverse _ind_first_r)) (while _continue { (if - (not (forEach - _reversed_indices - (fun (_i) { - (@= _cycles _i (- (@ _cycles _i) 1)) - (if (= 0 (@ _cycles _i)) - { - (let _at_i (@ _indices _i)) - (mut _k _i) - (while (< _k _len) { - (if (< (+ 1 _k) _len) - (@= _indices _k (@ _indices (+ 1 _k)))) - (set _k (+ 1 _k)) }) - (@= _indices -1 _at_i) - (@= _cycles _i (- _len _i)) } - { - (let _j (* -1 (@ _cycles _i))) - (let _ind_j (@ _indices _j)) - (@= _indices _j (@ _indices _i)) - (@= _indices _i _ind_j) - (if (= stopIteration (_f (select _L (select _indices _ind_first_r)))) - (set _continue false)) - stopIteration }) }))) + (not + (forEach + _reversed_indices + (fun (_i) { + (@= _cycles _i (- (@ _cycles _i) 1)) + (if (= 0 (@ _cycles _i)) + { + (let _at_i (@ _indices _i)) + (mut _k _i) + (while (< _k _len) { + (if (< (+ 1 _k) _len) (@= _indices _k (@ _indices (+ 1 _k)))) + (set _k (+ 1 _k)) }) + (@= _indices -1 _at_i) + (@= _cycles _i (- _len _i)) } + { + (let _j (* -1 (@ _cycles _i))) + (let _ind_j (@ _indices _j)) + (@= _indices _j (@ _indices _i)) + (@= _indices _i _ind_j) + (if (= stopIteration (_f (select _L (select _indices _ind_first_r)))) + (set _continue false)) + stopIteration }) }))) (set _continue false)) }) }) }) }))