diff options
author | inoas <mail@inoas.com> | 2022-10-27 21:36:34 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-27 22:36:34 +0100 |
commit | 5cd94fd14ae3d674b679542f56c73247dd7a2e77 (patch) | |
tree | 42690732b3337c8b1360422e51289a0fe3df6a13 /src | |
parent | 93c3223e8e5d5f9ba2a4020b18bed5802c63bdff (diff) | |
download | gleam_stdlib-5cd94fd14ae3d674b679542f56c73247dd7a2e77.tar.gz gleam_stdlib-5cd94fd14ae3d674b679542f56c73247dd7a2e77.zip |
fix list.permutation on lists with non unique item values (#358)
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/list.gleam | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam index 268642d..9a875d0 100644 --- a/src/gleam/list.gleam +++ b/src/gleam/list.gleam @@ -1443,18 +1443,34 @@ pub fn partition( /// [[1, 2], [2, 1]] /// ``` /// +/// Notice, that this function is not tail recursive: +/// +/// The execution limits on permutations are iterations rather than stack size; +/// for a permutation with `10` items a non tail recursive algorithm will at +/// worst built up a stack size of `10` before it goes back to `1` eventually, +/// while a permutation of say `5_000` items will not compute, in reasonable +/// time, despite not exceeding stack size. +/// pub fn permutations(l: List(a)) -> List(List(a)) { case l { [] -> [[]] _ -> - map( - l, - fn(x) { - filter(l, fn(y) { y != x }) - |> permutations - |> map(append([x], _)) - }, - ) + l + |> index_map(fn(i_idx, i) { + l + |> index_fold( + [], + fn(acc, j, j_idx) { + case i_idx == j_idx { + True -> acc + False -> [j, ..acc] + } + }, + ) + |> reverse + |> permutations + |> map(fn(permutation) { [i, ..permutation] }) + }) |> flatten } } |