|
| 1 | +:js |
1 | 2 | import "../../../mlscript-compile/Stack.mls"
|
| 3 | +import "../../../mlscript-compile/Iter.mls" |
2 | 4 | import "../../../mlscript-compile/Str.mls"
|
3 | 5 |
|
4 | 6 | open Stack
|
5 |
| -open Str |
6 | 7 |
|
7 |
| -type List[A] = Nil | Cons[A] |
| 8 | +fun showList(xs) = "[" + xs Iter.fromStack() Iter.joined(", ") + "]" |
8 | 9 |
|
9 |
| -fun (|>) pipe(x, f) = f(x) |
10 |
| - |
11 |
| -fun (:::) appendAll[A](xs: List[A], ys: List[A]): List[A] = |
12 |
| - if xs is |
13 |
| - Nil then ys |
14 |
| - Cons(x, xs') then x :: (xs' ::: ys) |
15 |
| -fun (:+) append[A](xs, x): List[A] = xs ::: (x :: Nil) |
16 |
| -fun reverse(xs) = |
17 |
| - fun aux(acc, xs) = |
18 |
| - if xs is |
19 |
| - Nil then acc |
20 |
| - Cons(x, xs') then aux(x :: acc, xs') |
21 |
| - aux(Nil, xs) |
22 |
| -fun join(sep) = |
23 |
| - fun aux(acc, xs) = |
24 |
| - if xs is |
25 |
| - Nil then acc |
26 |
| - Cons(x, xs') then aux(acc ~ sep ~ Str.from(x), xs') |
27 |
| - (xs) => |
28 |
| - if xs is |
29 |
| - Cons(x, xs') then aux(Str.from(x), xs') |
30 |
| - Nil then "" |
31 |
| -fun showList(xs) = "[" ~ join(", ")(xs) ~ "]" |
32 | 10 | fun foldLeft(f)(z) =
|
33 | 11 | fun aux(acc, xs) =
|
34 | 12 | if xs is
|
35 | 13 | Nil then acc
|
36 | 14 | Cons(x, xs') then aux(f(acc, x), xs')
|
37 | 15 | (xs) => aux(z, xs)
|
38 |
| -fun map(f, xs) = |
39 |
| - if xs is |
40 |
| - Nil then Nil |
41 |
| - Cons(x, xs') then f(x) :: map(f, xs') |
42 |
| -fun showListList(xs) = "[" ~ join(", ")(map(showList, xs)) ~ "]" |
43 | 16 |
|
44 |
| -fun insertAllPositions(z) = |
45 |
| - fun aux(prev, acc, xs) = |
46 |
| - if xs is |
47 |
| - Nil then ((prev :+ z) :: acc) |> reverse |
48 |
| - Cons(head, tail) then |
49 |
| - let nu = ((prev :+ z) ::: xs) |
50 |
| - aux(prev :+ head, nu :: acc, tail) |
51 |
| - xs => aux(Nil, Nil, xs) |
| 17 | +fun showLists(xs) = print of |
| 18 | + "[\n" + xs Iter.fromStack() Iter.mapping(showList) Iter.mapping(s => " " + s) Iter.joined(",\n") + "\n]" |
52 | 19 |
|
53 |
| -insertAllPositions(0)(1 :: 2 :: 3 :: Nil) |> showListList |
| 20 | +fun (~>..) insertAllPositions(z, xs) = |
| 21 | + fun go(prev, lists, next) = |
| 22 | + if next is |
| 23 | + Nil then ((prev :+ z) :: lists) |> reverse |
| 24 | + head :: tail then |
| 25 | + let nu = ((prev :+ z) ::: next) |
| 26 | + go(prev :+ head, nu :: lists, tail) |
| 27 | + go(Nil, Nil, xs) |
| 28 | + |
| 29 | +0 ~>.. (1 :: 2 :: 3 :: Nil) |> showLists |
| 30 | +//│ > [ |
| 31 | +//│ > [0, 1, 2, 3], |
| 32 | +//│ > [1, 0, 2, 3], |
| 33 | +//│ > [1, 2, 0, 3], |
| 34 | +//│ > [1, 2, 3, 0] |
| 35 | +//│ > ] |
54 | 36 |
|
55 | 37 | fun permutations(xs) =
|
56 | 38 | if xs is
|
57 | 39 | Nil then Nil
|
58 |
| - Cons(x, Nil) then (x :: Nil) :: Nil |
59 |
| - Cons(x, xs') then foldLeft((acc, ys) => acc ::: insertAllPositions(x)(ys))(Nil)(permutations(xs')) |
| 40 | + x :: Nil then (x :: Nil) :: Nil |
| 41 | + x :: xs' then permutations(xs') |
| 42 | + Iter.fromStack() |
| 43 | + Iter.folded of Nil, (acc, ys) => acc ::: (x ~>.. ys) |
60 | 44 |
|
61 |
| -permutations(Nil) |> showListList |
62 |
| -permutations(1 :: Nil) |> showListList |
63 |
| -permutations(1 :: 2 :: Nil) |> showListList |
64 |
| -permutations(1 :: 2 :: 3 :: Nil) |> showListList |
| 45 | +permutations(Nil) |> showLists |
| 46 | +//│ > [ |
| 47 | +//│ > |
| 48 | +//│ > ] |
65 | 49 |
|
66 |
| -fun filterNot(f, xs) = |
67 |
| - if xs is |
68 |
| - Nil then Nil |
69 |
| - Cons(x, xs') then |
70 |
| - if f(x) then filterNot(f, xs') |
71 |
| - else x :: filterNot(f, xs') |
| 50 | +permutations(1 :: Nil) |> showLists |
| 51 | +//│ > [ |
| 52 | +//│ > [1] |
| 53 | +//│ > ] |
72 | 54 |
|
73 |
| -fun permutations'(xs) = |
74 |
| - if xs is |
75 |
| - Nil then Nil |
76 |
| - Cons(x, Nil) then (x :: Nil) :: Nil |
77 |
| - else |
78 |
| - let f(acc, x) = acc ::: map((ys) => x :: ys, permutations'(filterNot((y) => x == y, xs))) |
79 |
| - foldLeft(f)(Nil)(xs) |
80 |
| - |
81 |
| -permutations'(Nil) |> showListList |
82 |
| -permutations'(1 :: Nil) |> showListList |
83 |
| -permutations'(1 :: 2 :: Nil) |> showListList |
84 |
| -permutations'(1 :: 2 :: 3 :: Nil) |> showListList |
| 55 | +permutations(1 :: 2 :: Nil) |> showLists |
| 56 | +//│ > [ |
| 57 | +//│ > [1, 2], |
| 58 | +//│ > [2, 1] |
| 59 | +//│ > ] |
| 60 | + |
| 61 | +permutations(1 :: 2 :: 3 :: Nil) |> showLists |
| 62 | +//│ > [ |
| 63 | +//│ > [1, 2, 3], |
| 64 | +//│ > [2, 1, 3], |
| 65 | +//│ > [2, 3, 1], |
| 66 | +//│ > [1, 3, 2], |
| 67 | +//│ > [3, 1, 2], |
| 68 | +//│ > [3, 2, 1] |
| 69 | +//│ > ] |
| 70 | + |
| 71 | +fun permutations'(xs) = if xs is |
| 72 | + Nil then Nil |
| 73 | + Cons(x, Nil) then (x :: Nil) :: Nil |
| 74 | + else xs |
| 75 | + Iter.fromStack() |
| 76 | + Iter.folded of Nil, (acc, x) => acc ::: permutations'(xs filter of (y) => x != y) |
| 77 | + Iter.fromStack() |
| 78 | + Iter.mapping((ys) => x :: ys) |
| 79 | + Iter.toStack() |
| 80 | + |
| 81 | +permutations'(Nil) |> showLists |
| 82 | +//│ > [ |
| 83 | +//│ > |
| 84 | +//│ > ] |
| 85 | + |
| 86 | +permutations'(1 :: Nil) |> showLists |
| 87 | +//│ > [ |
| 88 | +//│ > [1] |
| 89 | +//│ > ] |
| 90 | + |
| 91 | +permutations'(1 :: 2 :: Nil) |> showLists |
| 92 | +//│ > [ |
| 93 | +//│ > [1, 2], |
| 94 | +//│ > [2, 1] |
| 95 | +//│ > ] |
| 96 | + |
| 97 | +permutations'(1 :: 2 :: 3 :: Nil) |> showLists |
| 98 | +//│ > [ |
| 99 | +//│ > [1, 2, 3], |
| 100 | +//│ > [1, 3, 2], |
| 101 | +//│ > [2, 1, 3], |
| 102 | +//│ > [2, 3, 1], |
| 103 | +//│ > [3, 1, 2], |
| 104 | +//│ > [3, 2, 1] |
| 105 | +//│ > ] |
| 106 | + |
| 107 | +permutations'(1 :: 2 :: 3 :: 4 :: Nil) |> showLists |
| 108 | +//│ > [ |
| 109 | +//│ > [1, 2, 3, 4], |
| 110 | +//│ > [1, 2, 4, 3], |
| 111 | +//│ > [1, 3, 2, 4], |
| 112 | +//│ > [1, 3, 4, 2], |
| 113 | +//│ > [1, 4, 2, 3], |
| 114 | +//│ > [1, 4, 3, 2], |
| 115 | +//│ > [2, 1, 3, 4], |
| 116 | +//│ > [2, 1, 4, 3], |
| 117 | +//│ > [2, 3, 1, 4], |
| 118 | +//│ > [2, 3, 4, 1], |
| 119 | +//│ > [2, 4, 1, 3], |
| 120 | +//│ > [2, 4, 3, 1], |
| 121 | +//│ > [3, 1, 2, 4], |
| 122 | +//│ > [3, 1, 4, 2], |
| 123 | +//│ > [3, 2, 1, 4], |
| 124 | +//│ > [3, 2, 4, 1], |
| 125 | +//│ > [3, 4, 1, 2], |
| 126 | +//│ > [3, 4, 2, 1], |
| 127 | +//│ > [4, 1, 2, 3], |
| 128 | +//│ > [4, 1, 3, 2], |
| 129 | +//│ > [4, 2, 1, 3], |
| 130 | +//│ > [4, 2, 3, 1], |
| 131 | +//│ > [4, 3, 1, 2], |
| 132 | +//│ > [4, 3, 2, 1] |
| 133 | +//│ > ] |
0 commit comments