## 1.1 - Product ```Ocaml # let rec product = function | [] -> 0 | x::t -> x * product t;; ``` ## 1.2 - Count ```Ocaml # let rec count x n = if x = [] then 0 else let e::t = x in if e = x then 1 + count t n else count t n;; (* Correction *) # let rec count x = function | [] -> 0 | e::t -> (if x = e then 1 else 0) + count x t;; val count = 'a -> 'a list -> int = ``` ## 1.3 - Search ```Ocaml # let rec search x n = if x = [] then 0 else let e::t = x in if e = x then true else search t n;; (* Correction *) # let search x = function | [] -> false | e::t -> x = e || search x t | _::t -> search x t ;; val search 'a -> 'a list -> bool = ``` ## 1.4 - $n^{th}$ ```Ocaml # let nth l n = if n <= 0 then invalid_arg "n <= 0" else let rec nthrec = function | ([],_) -> failwith "list too short" | (h::_,1)-> h | (_::t, n) -> nthrec(t, n-1) in ntrec(l, n);; val nth 'a list -> int -> 'a = ``` ## 1.5 - Maximum ```Ocaml # let rec max_value list = match list with | [] -> failwith "La liste est vide" | [x] -> x | hd :: tl -> let max_tail = max_value tl in if hd > max_tail then hd else max_tail;; (* v2 *) # let max_value list = if list = [] then failwith "la list est vide" else let rec mv = match list with | [x] -> x | hd :: tl -> let max_tail = max_value tl in if hd > max_tail then hd else max_tail in mv list;; (* Correction *) let maximum = function [] -> invalid_arg "Pas bô" | e::t -> (let rec max_rec m = function []-> m |e::t -> max_rec (if e>m then e else m) t in max_rec e t);; ``` ## 1.6 - Bonus second ```Ocaml # let rec second_smallest list = match list with | [] | [_] -> failwith "La liste ne contient pas au moins deux éléments distincts" | [x; y] -> if x < y then y else x | hd1 :: hd2 :: tl -> let min1, min2 = if hd1 < hd2 then (hd1, hd2) else (hd2, hd1) in let rec find_second_smallest rest = match rest with | [] -> min2 | hd :: tl -> if hd < min1 then find_second_smallest (min1 :: tl) else if hd < min2 && hd > min1 then find_second_smallest (hd :: min1 :: tl) else find_second_smallest (min2 :: tl) in find_second_smallest tl;; ``` ## Exercise 2.1 ```Ocaml let rec arith_list n a1 r = if n <= 0 then [] else a1 :: arithmetic_list (n - 1) (a1 + r) r;; (*Other solution*) # let arith_list n a1 r = if n <= 0 then invalid_arg "invalid rank n" else let rec f ai = function | 0 -> [] | i -> (a1+(n-i)+r)::f(ai+r) (i-1) in f ai n;; ``` ## Exercise 2.2 ```Ocaml let concatenate_lists lst1 lst2 = lst1 @ lst2;; ``` ## Exercise 3.1 ```Ocaml let rec growing = function | [] | [_] -> true | x :: y :: rest -> if x <= y then growing (y :: rest) else false;; let growing = function |[] -> true |l -> let rec g = function |[_]-> true | e1::e2::_ -> when e1 > e2 -> false | _::t -> gt in g l;; ``` ## Exercise 3.2 ```ocaml let rec delete x = function | [] -> [] | e::i -> if x == e then i else e::delete x i (* Correction *) let rec delete x = function |[] -> [] |e::t -> if e = x then t else if x < e then e::t else e::delete x t ;; val delete: int -> 'a list -> list = ``` ## Exercise 3.3 ```Ocaml # let rec length l = if l = [] then 0 else let e::t = l in 1 +. length t;; #let rec insert x i list = if x < 0 then invalid_arg "negative rank" else if i > length list then failwith "Out of bound" else (* Correction *) let insert_nth w i list = if i <= 0 then invalid_arg "negative rank" else let rec insrec i = function (1,l) -> x::l | (_, []) -> failwith "out of bound" | (i, e::t) -> e::insrec(i-1, t) in insrec i list;; val insert_nth: 'a -> int -> 'a list -> 'a list = ``` ## Exercise 3.4 ```Ocaml # let insert_post x y = function | [] -> failwith "list is too large or empty" | e::t -> if e = y then e::x::t else e::insert_post x y t;; val insert_post : 'a -> 'a -> a' list -> list = ``` ## Exercise 3.5 ```Ocaml let rec reverse = function | [] -> [] | e::t -> reverse t@[e];; val reverse : 'a list -> 'a list = (* Correction *) # let reverse l = let rec rev rl = function [] -> rl | e::t -> rev(e::rl) l in rev [] l val reverse: 'a list -> 'a list = ``` ## Exercise 4.1 ```Ocaml let rec equals l = function | [] when l = [] -> true | [] -> false | e::t -> if l = [] then false else (let e2::l2 = l in e = e2 + equal (l-1)) val equals = 'a list -> 'a list -> bool = ``` ## Exercise 4.2 ```Ocaml let shared l1 l2 = function | [] -> [] | e::t -> let rec s l2 = function |e::t -> if e = e1 then e::sharede t t2 else if e2 > e then shared t (e2::t2) else shared (e::t) t2;; val shard = 'a list -> 'a list -> 'a list -> 'a list = ``` ## Exercise 5.1 ```Ocaml let assos k = function [] -> failwith "not found" | (k2, v2)::t when k2 = k -> v2 | (k2, v2):: t when k < k2 -> faiwith "not found" | e::t -> assoc k t val assos = 'a -> ('a + 'b) list -> 'b = (*Correction*) let assoc k l = if k < 0 then invalid_arg "k not a natural" else let rec findkey k = function [] -> failwith "not found" | (ke, ve)::t when k = ke -> ve | (ke, ve)::t when k < ke -> failwith "not found" | (ke, ve)::t -> findkey k t in findkey l;; val assoc: int -> (int * 'a)list -> 'a = ``` ## Exercise 5.2 ```Ocaml let rec flattten = function | [] -> [] | e::t -> (match e with | [] -> flatten t | e2::t2 -> e2==flatten(2::t));; val flatten: 'a list list -> 'a list = ``` Complexity : $O(\sum_{\forall{l\in{(el::ll)}}}^{}1+length(l))$ ## Exercise 6.1 ```Ocaml let rec decompose = function |