# 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"