diff --git a/99.nix b/99.nix new file mode 100644 index 0000000..e68f27b --- /dev/null +++ b/99.nix @@ -0,0 +1,72 @@ +# Based on the Ninety-Nine Lisp Problems: +# https://www.ic.unicamp.br/~meidanis/courses/mc336/problemas-lisp/L-99_Ninety-Nine_Lisp_Problems.html +# and following the format on OCaml's site: https://ocaml.org/exercises +# Solved only using `builtins.head` and `builtins.tail` to start + +let + head = builtins.head; + tail = builtins.tail; + + # Problem 1 +in let + last = lst: + if lst == [ ] then + null + else if (tail lst) == [ ] then + head lst + else + last (tail lst); +in assert last [ ] == null; +assert last [ 1 ] == 1; +assert last [ 1 2 3 ] == 3; + +# Problem 2 +let + last-two = lst: + if lst == [ ] || (tail lst) == [ ] then + null + else if (tail (tail lst)) == [ ] then + let + fst = head lst; + snd = head (tail lst); + in [ fst snd ] + else + last-two (tail lst); +in assert last-two [ ] == null; +assert last-two [ 1 ] == null; +assert last-two [ 1 2 ] == [ 1 2 ]; +assert last-two [ 1 2 3 ] == [ 2 3 ]; + +# Problem 3 +let + at = lst: n: + if lst == [ ] then + throw "Index out-of-bounds" + else if n == 0 then + head lst + else + at (tail lst) (n - 1); +in assert !(builtins.tryEval (at [ ] 0)).success; +assert !(builtins.tryEval (at [ 1 2 3 ] 4)).success; +assert at [ 1 2 3 ] 0 == 1; +assert at [ 1 2 3 ] 1 == 2; +assert at [ 1 2 3 ] 2 == 3; + +# Problem 4 +let length = lst: if lst == [ ] then 0 else 1 + length (tail lst); +in assert length [ ] == 0; +assert length [ 1 ] == 1; +assert length [ 1 2 3 ] == 3; + +# Problem 5 +let + rev = lst: + let + rev' = lst: acc: + if lst == [ ] then acc else rev' (tail lst) ([ (head lst) ] ++ acc); + in rev' lst [ ]; +in assert rev [ ] == [ ]; +assert rev [ 1 ] == [ 1 ]; +assert rev [ 1 2 3 ] == [ 3 2 1 ]; +assert rev [ 1 2 1 ] == [ 1 2 1 ]; +"ok"