epicours/Algo/Courses/Chapter 6 - Lists (Exercises).md

3.7 KiB

1.1 - Product

# let rec product = function
	| [] -> 0
	| x::t -> x * product t;;

1.2 - Count

# 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 = <fun>
# 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 = <fun>

1.4 - n^{th}

# 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 = <fun>

1.5 - Maximum

# 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

# 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

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

let concatenate_lists lst1 lst2 =
  lst1 @ lst2;;

Exercise 3.1

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

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 = <fun>

Exercise 3.3

# 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 = <fun>