feat: add first 5 99 problems in nix

This commit is contained in:
Lucas Sta Maria 2025-08-15 13:36:45 +00:00
parent 6dec4858e4
commit 6fec104f2f
Signed by: lucas
GPG key ID: F07FB16A826E3B47

72
99.nix Normal file
View file

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