OCAML CS3110 - Unit 3 Practice
let l1 = [1; 2; 3; 4; 5]
let l2 = 1 :: 2 :: 3 :: 4 :: 5 :: []
let l3 = [1] @ [2; 3; 4] @ [5]
let rec product (xs : 'a list) : int =
match xs with
| [] -> 1
| h :: t -> h * product t
let rec concat (xs : string list) : string =
match xs with
| [] -> ""
| h :: t -> h ^ concat t
(* patten match *)
let rec pat1 = function
| [] -> false
| h :: _ -> h = "bigred"
let pat2 = function
| _ :: _ :: [] | _ :: _ :: _ :: _ :: [] -> true
| _ -> false
let pat3 = function
| x :: y :: [] -> x = y
| _ -> false
(* library *)
let fiveth (xs : int list) : int =
if List.length xs >= 5 then List.nth xs 4 else 0
let downlist (xs : int list) : int list =
List.sort Stdlib.compare xs |> List.rev
(* library puzzle *)
let lastele xs =
List.nth (List.rev xs) 0
let haszero (xs : int list) =
List.exists (fun x -> x = 0) xs
(* take drop *)
let rec take n xs : int list =
match n with
| 0 -> []
| _ -> begin
match xs with
| [] -> []
| h :: t -> h :: take (n - 1) t
end
let rec drop n xs : int list =
match n with
| 0 -> xs
| _ -> begin
match xs with
| [] -> []
| h :: t -> drop (n - 1) t
end
(* unimodal *)
let rec is_dec (xs : int list) : bool =
match xs with
| [] | [_] -> true
| h1 :: (h2 :: t1 as t) -> h1 >= h2 && is_dec t
let rec is_inc_dec = function
| [] | [_] -> true
| a :: (b :: t) as t1 ->
if a <= b then is_inc_dec t else is_dec t1
let is_unimodal xs = is_inc_dec xs
(* powerset *)
let rec powerset (xs : int list) : int list list =
let ss = List.sort Stdlib.compare xs in
match ss with
| [] -> [[]]
| h :: t -> let p = powerset t in
List.map (List.cons h) p @ p
(* print int list rec *)
let rec print_int_list (xs : int list) : unit =
match xs with
| [] -> ()
| h :: t -> print_endline @@ string_of_int h; print_int_list t
(* print int list iter *)
let print_int_list' xs =
List.iter (fun x -> print_endline @@ string_of_int x) xs
(* student *)
type student = {first_name : string; last_name : string; gpa : float}
let a1 : student = {first_name = "Line"; last_name = "BuBu"; gpa = 3.1}
let student_name stu =
(stu.first_name, stu.last_name)
let student_create f l g : student =
{first_name = f; last_name = l; gpa = g}
(* pokerecord *)
type poketype = Normal | Fire | Water
type pokemen = {name : string; hp : int; ptype : poketype}
let charizard = {name = "charizard"; hp = 78; ptype = Fire}
let squirtle = {name = "squirtle"; hp = 44; ptype = Water}
(* safe hd and tl *)
let safe_hd = function
| [] -> None
| h :: _ -> Some h
let rec safe_tl = function
| [] -> None
| _ :: t -> match t with
| [] -> failwith "can't be trigged"
| h :: [] -> Some h
| _ -> safe_tl t
(* pokefun *)
let rec max_hp (xs : pokemen list) : pokemen option =
match xs with
| [] -> None
| h :: t -> match max_hp t with
| None -> Some h
| Some h1 -> Some (if h1.hp >= h.hp then h1 else h)
(* date before *)
type date = int * int * int
let is_before (x : date) (y : date) : bool =
let (x1,x2,x3) = x in
let (y1,y2,y3) = y in
x1 < y1 || (x1 = y1 && x2 < y2) || (x1 = y1 && x2 = y2 && x3 < y3)
(* earliest date *)
let rec earliest (xs : date list) : date option =
match xs with
| [] -> None
| h :: t -> match earliest t with
| None -> Some h
| Some h1 -> Some (if is_before h1 h then h1 else h)
(* assoc list *)
let insert k v lst = (k, v) :: lst
let rec lookup k = function
| [] -> None
| (k', v) :: t -> if k = k' then Some v else lookup k t
let mp = insert 1 "one" (insert 2 "two" (insert 3 "three" []))
let ck2 = lookup 2 mp
let ck4 = lookup 4 mp
(* cards *)
type suit = Hearts | Spades | Clubs | Diamonds
type rank = Number of int | Ace | Jack | Queen | King
type card = {suit : suit; rank : rank}
(* quadrant *)
type quad = I | II | III | IV
type sign = Neg | Zero | Pos
let sign (x : int) : sign =
if x = 0 then Zero else if x > 0 then Pos else Neg
let quadrant (point : int * int) : quad option =
let (x, y) = point in
match sign x, sign y with
| Pos, Pos -> Some I
| Neg, Pos -> Some II
| Neg, Neg -> Some III
| Pos, Neg -> Some IV
| _ -> None
let quadrant_when (point : int * int) : quad option =
let (x, y) = point in
match x, y with
| x, y when x > 0 && y > 0 -> Some I
| x, y when x < 0 && y > 0 -> Some II
| x, y when x < 0 && y < 0 -> Some III
| x, y when x > 0 && y < 0 -> Some IV
| _ -> None
(* depth *)
type 'a tree = Nil | Node of 'a * 'a tree * 'a tree
let rec depth (tree : 'a tree) : int =
match tree with
| Nil -> 0
| Node (_, l, r) -> max (1 + depth l) (1 + depth r)
(* shape *)
let rec shape (a : 'a tree) (b : 'a tree) : bool =
match a, b with
| Nil, Nil -> true
| Node (_, l1, r1) , Node (_, l2, r2) -> shape l1 l2 && shape r1 r2
| _ -> false
(* list max exn *)
let rec list_max = function
| [] -> failwith "empty"
| h :: [] -> h
| h :: t -> max h @@ list_max t
(* list max exn string *)
let list_max_string (xs : int list) : string =
match xs with
| [] -> "empty"
| _ -> string_of_int @@ list_max xs
(* is_bst *)
let is_bst : ('a * 'b) tree -> bool = fun xs ->
failwith "TODO"