From b6570114cbbfae345ccf24eb79b644656480532d Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Thu, 29 Jan 2026 16:13:37 -0800 Subject: [PATCH] add comments and tests --- lab03/kvtree.ml | 169 ++++++++++++++++++++++++++++++++++++++++++++---- lab03/part1.ml | 27 ++++++++ 2 files changed, 182 insertions(+), 14 deletions(-) diff --git a/lab03/kvtree.ml b/lab03/kvtree.ml index fa99d34..1f5bc85 100644 --- a/lab03/kvtree.ml +++ b/lab03/kvtree.ml @@ -1,21 +1,15 @@ +(* default comparator for testing *) +let scmp = String.compare;; + +(** [kvtree] is a key value tree where each node has a key, value, left and right *) type ('k, 'v) kvtree = Leaf | Node of 'k * 'v * ('k, 'v) kvtree * ('k, 'v) kvtree;; -let rec kvtree_size t = - match t with - | Leaf -> 0 - | Node (_, _, l, r) -> - 1 + kvtree_size l + kvtree_size r;; - -let rec kvtree_height t = - match t with - | Leaf -> 0 - | Node (_, _, l, r) -> - 1 + max (kvtree_height l) (kvtree_height r);; - +(* example of an empty kvtree *) let kvtree_empty = Leaf;; -let kvtree_is_empty t = t = Leaf;; - +(** [kvtree_insert ~cmp k v t] takes a comparator [~cmp], key [k], value [v], + and a kvtree [t] to insert the key and value [k, v] into the tree [t] in + the order specefied by the comparator [~cmp] to compare keys *) let rec kvtree_insert ~cmp k v t = match t with | Leaf -> Node (k, v, Leaf, Leaf) @@ -25,9 +19,83 @@ let rec kvtree_insert ~cmp k v t = Node (k', v', l, kvtree_insert ~cmp k v r) | _ -> t;; +(**/**)2 +let test_kvtree_insert () = + let a = Node ("Bread", 20, Leaf, Leaf) in + let b = Node ("Bread", 20, Leaf, Node("Mitch", 22, Leaf, Leaf)) in + let c = Node ("Bread", 20, Leaf, Node("Mitch", 22, Node("Luka", 19, Leaf, Leaf), Leaf)) in + assert (kvtree_insert ~cmp:scmp "Bread" 20 Leaf = a); + assert (kvtree_insert ~cmp:scmp "Mitch" 22 a = b); + assert (kvtree_insert ~cmp:scmp "Luka" 19 b = c) +(**/**) + +(** [kvtree_of_list ~cmp l] takes a list of pairs [l] and creates a + kvtree in the order specefied by the comparator [~cmp] to compare + keys *) let kvtree_of_list ~cmp l = List.fold_left (fun acc (k, v) -> kvtree_insert ~cmp k v acc) Leaf l;; +(**/**) +let test_kvtree_of_list () = + let a = Node ("Bread", 20, Leaf, Leaf) in + let b = Node ("Bread", 20, Leaf, Node("Mitch", 22, Leaf, Leaf)) in + assert (kvtree_of_list ~cmp:scmp [] = Leaf); + assert (kvtree_of_list ~cmp:scmp [("Bread", 20)] = a); + assert (kvtree_of_list ~cmp:scmp [("Bread", 20); ("Mitch", 22)] = b) +(**/**) + +(** [kvtree_is_empty t] takes a kvtree [t] and checks if it is empty or not *) +let kvtree_is_empty t = t = Leaf;; + +(**/**) +let test_kvtree_is_empty () = + let a = Node ("Bread", 20, Leaf, Leaf) in + let b = Node ("Bread", 20, Leaf, Node("Mitch", 22, Leaf, Leaf)) in + assert (kvtree_is_empty Leaf = true); + assert (kvtree_is_empty a = false); + assert (kvtree_is_empty b = false) +(**/**) + +(** [kvtree_size t] takes a kvtree [t] and returns the size of the tree + i.e. number of nodes *) +let rec kvtree_size t = + match t with + | Leaf -> 0 + | Node (_, _, l, r) -> + 1 + kvtree_size l + kvtree_size r;; + +(**/**) +let test_kvtree_size () = + let a = Node ("Bread", 20, Leaf, Leaf) in + let b = Node ("Bread", 20, Leaf, Node("Mitch", 22, Leaf, Leaf)) in + let c = Node ("Bread", 20, Leaf, Node("Mitch", 22, Node("Luka", 19, Leaf, Leaf), Leaf)) in + assert (kvtree_size Leaf = 0); + assert (kvtree_size a = 1); + assert (kvtree_size b = 2); + assert (kvtree_size c = 3) +(**/**) + +(** [kvtree_height t] takes a kvtree [t] and returns the height of + the tree (how deep the nodes go down in the tree) *) +let rec kvtree_height t = + match t with + | Leaf -> 0 + | Node (_, _, l, r) -> + 1 + max (kvtree_height l) (kvtree_height r);; + +(**/**) +let test_kvtree_height () = + let a = Node ("Bread", 20, Leaf, Leaf) in + let b = Node ("Bread", 20, Leaf, Node("Mitch", 22, Leaf, Leaf)) in + let c = Node ("Bread", 20, Leaf, Node("Mitch", 22, Node("Luka", 19, Leaf, Leaf), Leaf)) in + assert (kvtree_height Leaf = 0); + assert (kvtree_height a = 1); + assert (kvtree_height b = 2); + assert (kvtree_height c = 3) +(**/**) + +(** [kvtree_mem ~cmp k t] checks if a given key [k] is in a given kvtree + [t] in the order specified by the comparator [~cmp] *) let rec kvtree_mem ~cmp k t = match t with | Leaf -> false @@ -37,18 +105,55 @@ let rec kvtree_mem ~cmp k t = kvtree_mem ~cmp k r | _ -> true;; +(**/**) +let test_kvtree_mem () = + let a = Node ("Bread", 20, Leaf, Node("Mitch", 22, Node("Luka", 19, Leaf, Leaf), Leaf)) in + assert (kvtree_mem ~cmp:scmp "Bread" Leaf = false); + assert (kvtree_mem ~cmp:scmp "Bread" a = true); + assert (kvtree_mem ~cmp:scmp "Mitch" a = true); + assert (kvtree_mem ~cmp:scmp "Ryan" a = false) +(**/**) + +(** [kvtree_largest t] finds the largest key in a given kvtree [t] + and retursn the key value pair [k, v] *) let rec kvtree_largest t = match t with | Leaf -> failwith "kvtree_largest: empty tree" | Node (k, v, _, Leaf) -> (k, v) | Node (_, _, _, r) -> kvtree_largest r;; +(**/**) +(* largest by key not by value *) +let test_kvtree_largest () = + let a = Node ("Bread", 20, Leaf, Leaf) in + let b = Node ("Bread", 20, Leaf, Node("Mitch", 22, Leaf, Leaf)) in + let c = Node ("Bread", 20, Leaf, Node("Mitch", 22, Node("Luka", 19, Leaf, Leaf), Leaf)) in + assert (kvtree_largest a = ("Bread", 20)); + assert (kvtree_largest b = ("Mitch", 22)); + assert (kvtree_largest c = ("Mitch", 22)) +(**/**) + +(** [kvtree_smallest t] finds the smallest key in a given kvtree [t] + and retursn the key value pair [k, v] *) let rec kvtree_smallest t = match t with | Leaf -> failwith "kvtree_smallest: empty tree" | Node (k, v, Leaf, _) -> (k, v) | Node (_, _, l, _) -> kvtree_smallest l;; +(**/**) +(* smallest by key not by value *) +let test_kvtree_smallest () = + let a = Node ("Bread", 20, Leaf, Leaf) in + let b = Node ("Bread", 20, Leaf, Node("Mitch", 22, Leaf, Leaf)) in + let c = Node ("Bread", 20, Leaf, Node("Mitch", 22, Node("Luka", 19, Leaf, Leaf), Leaf)) in + assert (kvtree_smallest a = ("Bread", 20)); + assert (kvtree_smallest b = ("Bread", 20)); + assert (kvtree_smallest c = ("Bread", 20)) +(**/**) + +(** [kvtree_delete ~cmp k t] takes a key [k] and deletes it from a given + kvtree [t] in the order specefied by the comparator [~cmp] *) let rec kvtree_delete ~cmp k t = match t with | Leaf -> Leaf @@ -62,6 +167,20 @@ let rec kvtree_delete ~cmp k t = let (ks, vs) = kvtree_largest l in Node (ks, vs, kvtree_delete ~cmp ks l, r);; +(**/**) +let test_kvtree_delete () = + let a = Node ("Bread", 20, Leaf, Leaf) in + let b = Node ("Bread", 20, Leaf, Node("Mitch", 22, Leaf, Leaf)) in + let c = Node ("Bread", 20, Leaf, Node("Mitch", 22, Node("Luka", 19, Leaf, Leaf), Leaf)) in + let d = Node ("Bread", 20, Leaf, Node("Luka", 19, Leaf, Leaf)) in + assert (kvtree_delete ~cmp:scmp "Bread" a = Leaf); + assert (kvtree_delete ~cmp:scmp "Mitch" c = d); + assert (kvtree_delete ~cmp:scmp "Luka" c = b) +(**/**) + +(** [kvtree_find_opt ~cmp k t] takes a key [k] and a kvtree [t] and returns + and Optional value found from the given key [k]. Searching through the + tree in the order specefied by the comparator [~cmp] *) let rec kvtree_find_opt ~cmp k t = match t with | Leaf -> None @@ -70,3 +189,25 @@ let rec kvtree_find_opt ~cmp k t = | Node (k', _, _, r) when cmp k k' > 0 -> kvtree_find_opt ~cmp k r | Node (_, v, _, _) -> Some v;; + +(**/**) +let test_kvtree_find_opt () = + let a = Node ("Bread", 20, Leaf, Node("Mitch", 22, Node("Luka", 19, Leaf, Leaf), Leaf)) in + assert (kvtree_find_opt ~cmp:scmp "Luka" Leaf = None); + assert (kvtree_find_opt ~cmp:scmp "Ryan" a = None); + assert (kvtree_find_opt ~cmp:scmp "Bread" a = Some 20); + assert (kvtree_find_opt ~cmp:scmp "Mitch" a = Some 22) +(**/**) + +(**/**) +let run_all_tests () = + test_kvtree_insert(); + test_kvtree_of_list(); + test_kvtree_is_empty(); + test_kvtree_size(); + test_kvtree_height(); + test_kvtree_mem(); + test_kvtree_largest(); + test_kvtree_smallest(); + test_kvtree_delete(); + test_kvtree_find_opt() diff --git a/lab03/part1.ml b/lab03/part1.ml index f5aa132..08f3585 100644 --- a/lab03/part1.ml +++ b/lab03/part1.ml @@ -1,3 +1,5 @@ +(** [digits n] takes a positive integer [n] and returns + a list of integers of each digit in the number [n] *) let digits n = let rec digits' n acc = if n = 0 then acc @@ -5,5 +7,30 @@ let digits n = in digits' n [];; +(**/**) +let test_digits () = + assert (digits 0 = []); + assert (digits 123 = [1;2;3]); + assert (digits 123040 = [1;2;3;0;4;0]) +(**/**) + +(** [int_of_digits d] takes a list of positive integers [d] + and returns a single number where each digit is from the + list [d] + *) let int_of_digits d = (List.fold_left (fun x acc -> (x + acc) * 10) 0 d) / 10;; + +(**/**) +let test_int_of_digits () = + assert (int_of_digits [] = 0); + assert (int_of_digits [0] = 0); + assert (int_of_digits [0;0;1;2;3] = 123); + assert (int_of_digits [2;0;0;5] = 2005) +(**/**) + +(**/**) +let run_all_tests () = + test_digits(); + test_int_of_digits() +(**/**)