Files
comp3958/lab01/lab1.ml
T
2026-01-15 15:03:48 -08:00

155 lines
4.0 KiB
OCaml

(** [reverse l] returns the reverse order of list [l]; non tail recursive *)
let rec reverse l =
match l with
| [] -> []
| x :: xs -> reverse xs @ [x];;
(**/**)
let test_reverse () =
assert (reverse [] = []);
assert (reverse [1] = [1]);
assert (reverse [1; 2] = [2; 1])
(**/**)
(** [reverse_tr l] returns the reverse order of list [l]; tail recursive *)
let reverse_tr l =
let rec reverse_tr' acc l =
match l with
| [] -> acc
| x :: xs -> reverse_tr' (x :: acc) xs
in
reverse_tr' [] l;;
(**/**)
let test_reverse_tr () =
assert (reverse_tr [] = []);
assert (reverse_tr [1] = [1]);
assert (reverse_tr [1; 2] = [2; 1])
(**/**)
(** [zip l1 l2] combines elements from [l1] and [l2] into a
* new list of tuples; non tail recursive
*)
let rec zip l1 l2 =
match l1, l2 with
| [], _ | _, [] -> [] (* if l1 or l2 is empty, return empty *)
| x1 :: xs1, x2 :: xs2 ->
(x1, x2) :: zip xs1 xs2;;
(**/**)
let test_zip () =
assert (zip [] [] = []);
assert (zip [1] [] = []);
assert (zip [] ['a'] = []);
assert (zip [1; 2; 3] ['a'; 'b'] = [(1, 'a'); (2, 'b')]);
assert (zip [1; 2; 3] ['a'; 'b'; 'c'] = [(1, 'a'); (2, 'b'); (3, 'c')])
(**/**)
(** [zip_tr l1 l2] combines elements from [l1] and [l2] into a
* new list of tuples; tail recursive
*)
let zip_tr l1 l2 =
let rec zip_tr' acc l1 l2 =
match l1, l2 with
| [], _ | _, [] -> reverse_tr acc (* if l1 or l2 is empty, return empty *)
| x1 :: xs1, x2 :: xs2 ->
zip_tr' ((x1, x2) :: acc) xs1 xs2
in
zip_tr' [] l1 l2;;
(**/**)
let test_zip_tr () =
assert (zip_tr [] [] = []);
assert (zip_tr [1] [] = []);
assert (zip_tr [] ['a'] = []);
assert (zip_tr [1; 2; 3] ['a'; 'b'] = [(1, 'a'); (2, 'b')]);
assert (zip_tr [1; 2; 3] ['a'; 'b'; 'c'] = [(1, 'a'); (2, 'b'); (3, 'c')])
(**/**)
(** [unzip l] takes in a list of tuples [l] where each tuple is
* a pair, we seperate the pairs (x, y) into sepeate lists, ([x], [y])
* and return a tuple of both lists; non tail recursive *)
let rec unzip l =
match l with
| [] -> ([], [])
| (x, y) :: xys ->
let (l1, l2) = unzip xys in
x :: l1, y :: l2;;
(**/**)
let test_unzip () =
assert (unzip [] = ([], []));
assert (unzip [(1, 'a')] = ([1], ['a']));
assert (unzip [(1, 'a'); (2, 'b')] = ([1; 2], ['a'; 'b']))
(**/**)
(** [unzip_tr l] takes in a list of tuples [l] where each tuple is
* a pair, we seperate the pairs (x, y) into sepeate lists, ([x], [y])
* and return a tuple of both lists; tail recursive *)
let unzip_tr l =
let rec unzip_tr' (a1, a2) l =
match l with
| [] -> (a1, a2)
| (x, y) :: xys ->
unzip_tr' (x :: a1, y :: a2) xys
in
unzip_tr' ([], []) (reverse_tr l);;
(**/**)
let test_unzip_tr () =
assert (unzip_tr [] = ([], []));
assert (unzip_tr [(1, 'a')] = ([1], ['a']));
assert (unzip_tr [(1, 'a'); (2, 'b')] = ([1; 2], ['a'; 'b']))
(**/**)
(** [dedup l] takes in a list [l] and collapses consecutive duplicated
* elements into a single element; non tail recursive *)
let rec dedup l =
match l with
| [] -> []
| [x] -> l
| x :: y :: zs ->
if x = y then dedup (x :: zs)
else x :: dedup (y :: zs);;
(**/**)
let test_dedup () =
assert (dedup [] = []);
assert (dedup [1] = [1]);
assert (dedup [1; 2] = [1; 2]);
assert (dedup [1; 1; 2; 2; 2; 1; 3; 3; 2] = [1; 2; 1; 3; 2])
(**/**)
(** [dedup l] takes in a list [l] and collapses consecutive duplicated
* elements into a single element; tail recursive *)
let dedup_tr l =
let rec dedup' acc l =
match l with
| [] -> acc
| [x] -> l
| x :: y :: zs ->
if x = y then dedup' (x :: acc) (x :: zs)
else x :: dedup' (x :: acc) (y :: zs)
in
dedup' [] l;;
(**/**)
let test_dedup_tr () =
assert (dedup_tr [] = []);
assert (dedup_tr [1] = [1]);
assert (dedup_tr [1; 2] = [1; 2]);
assert (dedup_tr [1; 1; 2; 2; 2; 1; 3; 3; 2] = [1; 2; 1; 3; 2])
(**/**)
(**/**)
let run_all_tests () =
test_reverse();
test_reverse_tr();
test_zip();
test_zip_tr();
test_unzip();
test_unzip_tr();
test_dedup();
test_dedup_tr();
(**/**)