Skip to content
Snippets Groups Projects
Commit 380f95d7 authored by Sander Mathijs van Veen's avatar Sander Mathijs van Veen
Browse files

Finished assignments for week 4.

parent f374d866
No related branches found
No related tags found
No related merge requests found
(* Sort the list in ascending order using quicksort. *)
let rec quickSort (l: int list) = match l with
| [] -> []
| pivot::tail -> let left, right = List.partition (fun x -> x < pivot) tail
in quickSort left @ [pivot] @ quickSort right
;;
Printf.printf "8.1: %b\n" ((=)(quickSort [4;3;1;2]) [1;2;3;4])
(* Sort the list in ascending order using merge sort. *)
let rec mergeSort (l: int list) = match l with
| [] | [_] -> l
| _ ->
(* Split the lists into lists of length one (which are sorted by
* definition), and repeatedly merge the lists together. *)
let rec merge a b = match a, b with
| [], _ -> b
| _, [] -> a
| ha::ta, hb::tb when ha < hb -> ha::(merge ta b)
| ha::ta, hb::tb -> hb::(merge a tb)
(* Split the list "equally" in two parts: left and right. *)
in let rec split left right len = match left, len with
| [], _ | _, 0 -> (left, right)
| h::t, _ -> split t (h::right) (len - 1)
in let left, right = split l [] ((List.length l) / 2)
(* Recursively merge the left and right sorted lists. *)
in merge (mergeSort left) (mergeSort right)
;;
Printf.printf "8.2: %b\n" ((=)(mergeSort [4;3;1;2]) [1;2;3;4])
(* --- Assignment 9 --- *)
(* A trie node has a key, a value and a list of children. *)
type ('a, 'b) trie = Empty | Node of 'a list * 'b * ('a, 'b) trie list
(* Helper functions, Return a list, cutoff at the node where the key equals
* elem. *)
let rec front_of_lst lst elem = match lst with
| [] -> Empty
| t::h -> match t with
| Empty | Node([], _,_) -> Empty
| Node(c::d, _, _) when c == elem -> t
| Node(c::d, _, _) -> front_of_lst h elem
;;
(* Helper function, changes the value in a node to v. *)
let change_node_value node v = match node with
| Empty -> raise (Failure "Empty Node")
| Node(a,b,lst) -> Node(a,v,lst)
;;
(* Helper function: given a list of nodes, remove given node from the list and
* return the modified list. *)
let rec remove_node lst n =
let a = List.hd lst
in let b = List.tl lst
in match a, n with
| Empty, _ -> [a] @ remove_node b n
| Node([], g, h), _ -> [a]
| Node(t::l, g, h), Empty -> [a] @ remove_node b n
| Node(t::l, g, h), Node(tt::ll, _, _) when t == tt -> remove_node b n
| Node(t::l, g, h), Node(_, _, _) -> [a] @ remove_node b n
;;
(* Insert a node into the trie. *)
let rec insert trie k v =
match trie, k with
| Empty, [] -> Node([], None, [])
| Empty, _ -> insert (Node([], None, [])) k v
| Node(a, b, lst), [] -> trie
| Node(a, b, lst), c::d ->
let found = front_of_lst lst c in match d, found with
| [], Empty -> Node(a, b, lst @ [Node([c], Some v, [])])
| [], _ -> Node(a, b, (remove_node lst found)
@ [(change_node_value found (Some v))])
| _, Empty -> Node(a, b, lst @ [insert (Node([c], None, [])) d v])
| _, _ -> Node(a, b, [insert found d v] @ (remove_node lst found))
;;
(* Helper function: check if a node equals the given part of the key in a list
* of nodes. *)
let rec check lst k = match lst, k with
| [], _ -> Empty
| Node(a, _, _)::b, k when a = [k] -> List.hd lst
| a::b, k -> check b k
;;
(* Remove a value from the trie. The value is replaced by None. *)
let rec remove trie k = match trie, k with
| Empty, _ -> trie
| Node(a,b,lst), [] -> change_node_value trie None
| Node(a,b,lst), h::t ->
let in_list = check lst h in match in_list with
| Empty -> trie
| _ -> Node(a,b, [remove in_list t] @ (remove_node lst in_list))
;;
(* Returns the value that is associated with the key. *)
(* type 'a option = Some of 'a | None *)
let rec lookup trie k = match trie, k with
| Empty,_ -> None
| Node(a,b,lst),[] -> b
| Node(a,b,lst),h::t ->
let in_list = check lst h in match in_list with
| Empty -> None
| _ -> lookup in_list t
;;
(* --- Assignment 10 --- *)
(* I explicitly replaced the following names given in the assignment, because
* the original name were unclear or wrong:
* - "rel_op" -> "equal_op", since these operators express (in)equality.
* - "mon_op" -> "unary_op", since these operators are unary (one parameter).
* - "bin_op" -> "binary_op", for consistency with unary_op. *)
type arith_op = Plus | Minus | Times | Divide | Modulo
type equal_op = Eq | Neq | Lt | Lte | Gt | Gte
type logic_op = And | Or
type unary_op = Negation | Not
type const = BoolConst of bool | IntConst of int
type binary_op =
| ArithOp of arith_op
| EqualOp of equal_op
| LogicOp of logic_op
;;
type expr =
| Enclosure of expr
| BinaryOp of expr * binary_op * expr
| UnaryOp of unary_op * expr
| Id of string
| Const of const
;;
let eval_arith_op = function
| Plus -> "+"
| Minus -> "-"
| Times -> "*"
| Divide -> "/"
| Modulo -> "mod"
;;
let eval_equal_op = function
| Eq -> "="
| Neq -> "!="
| Lt -> "<"
| Lte -> "<="
| Gt -> ">"
| Gte -> ">="
;;
let eval_logic_op = function
| And -> "&&"
| Or -> "||"
;;
let eval_unary_op = function
| Negation -> "-"
| Not -> "not"
;;
let eval_const = function
| IntConst i -> string_of_int i
| BoolConst b -> string_of_bool b
;;
let eval_binary_op = function
| ArithOp op -> eval_arith_op(op)
| EqualOp op -> eval_equal_op(op)
| LogicOp op -> eval_logic_op(op)
;;
let rec eval = function
| Enclosure e -> "(" ^ eval(e) ^ ")"
| BinaryOp (e1, op, e2) -> eval(e1) ^ " " ^ eval_binary_op(op) ^ " " ^ eval(e2)
| UnaryOp (op, e) -> eval_unary_op(op) ^ eval(e)
| Id id -> id
| Const c -> eval_const(c)
;;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment