vault backup: 2023-11-13 13:50:53
This commit is contained in:
302
Algo/B1/Courses/Chapter 6 - Lists (Exercises).md
Normal file
302
Algo/B1/Courses/Chapter 6 - Lists (Exercises).md
Normal file
@ -0,0 +1,302 @@
|
||||
## 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 = <fun>
|
||||
```
|
||||
|
||||
## 1.3 - Search
|
||||
```Ocaml
|
||||
# let rec search x n =
|
||||
if x = [] then
|
||||
false
|
||||
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}$
|
||||
```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 = <fun>
|
||||
|
||||
```
|
||||
|
||||
## 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 a i = 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 = <fun>
|
||||
|
||||
```
|
||||
|
||||
## 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 = <fun>
|
||||
```
|
||||
|
||||
## 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 = <fun>
|
||||
```
|
||||
|
||||
## Exercise 3.5
|
||||
```Ocaml
|
||||
let rec reverse = function
|
||||
| [] -> []
|
||||
| e::t -> reverse t@[e];;
|
||||
val reverse : 'a list -> 'a list = <fun>
|
||||
|
||||
(* 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 = <fun>
|
||||
```
|
||||
|
||||
## 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 = <fun>
|
||||
```
|
||||
|
||||
## 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 = <fun>
|
||||
```
|
||||
|
||||
## 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 = <fun>
|
||||
|
||||
(*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 = <fun>
|
||||
```
|
||||
|
||||
## 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 = <fun>
|
||||
```
|
||||
Complexity : $O(\sum_{\forall{l\in{(el::ll)}}}^{}1+length(l))$
|
||||
|
||||
## Exercise 6.1
|
||||
```Ocaml
|
||||
let rec decompose x =
|
||||
let l = [] in
|
||||
if x = 1 then x::l
|
||||
else if x mod 2 == 0 then
|
||||
decompose(x/2)
|
||||
else if x mod 3 = 0 then
|
||||
decompose(x/3)
|
||||
else if x mod 5 = 0 then
|
||||
decompose(x/5)
|
||||
else if x mod 7 = 0 then
|
||||
decompose(x/7)
|
||||
else if x mod 9 = 0 then
|
||||
decompose(x/9)
|
||||
else if x mod 11 = 0 then
|
||||
decompose(x/11)
|
||||
else if x mod 13 = 0 then
|
||||
decompose(x/13)
|
||||
else x::l
|
||||
|
153
Algo/B1/Courses/Chapter 6 - Lists.md
Normal file
153
Algo/B1/Courses/Chapter 6 - Lists.md
Normal file
@ -0,0 +1,153 @@
|
||||
<center><img src="https://i.redd.it/ro23smjrij941.jpg" height=auto width=300/> </center>
|
||||
|
||||
## Linear list
|
||||
### Def
|
||||
A linear data structure is a list where the elements must be treated sequentially.
|
||||
$$ \lambda = <e_1, e_2, e_3, ..., e_n> $$
|
||||
> $e_1$ is the rank of the value e. In linear list, we start at 0 because we don't use index list.
|
||||
|
||||
The linear list is evolutive, you can add or remove elements. Also, the linear list can be empty.
|
||||
|
||||
### List in CAML
|
||||
```Ocaml
|
||||
# [1 ; 2 ; 3];;
|
||||
_: int list = [1, 2, 3]
|
||||
```
|
||||
> In CAML, all the element in the list have to be of the same type.
|
||||
|
||||
```Ocaml
|
||||
# let l1 = ['H'; 'i'];;
|
||||
val l1 : char list = ['H'; 'i']
|
||||
# let l2 = ['C'; 'a'; 'm'; 'l'];;
|
||||
val l2 : char list = ['C' ; 'a' ;'m'; 'l']
|
||||
# [l1; l2]
|
||||
_: char list list : [['H'; 'i'] ; ['C' ; 'a' ;'m'; 'l']]
|
||||
```
|
||||
> The expression `char list` is the element type of the evaluation
|
||||
|
||||
```Ocaml
|
||||
# ["H" ; 'i'];;
|
||||
Error: string ≠ char
|
||||
# [(function x -> x + 10); (function y -> 2*y)];;
|
||||
_: (int -> int) list = [<fun> ; <fun>]
|
||||
```
|
||||
|
||||
## The empty list
|
||||
```Ocaml
|
||||
# [];;
|
||||
-: a list = []
|
||||
```
|
||||
## Recursive type
|
||||
**`e::t` => adds the element e at the head (`e`) of the list tail (`f`)**
|
||||
|
||||
```Ocaml
|
||||
# 1::[2; 3];;
|
||||
_: int list = [1; 2; 3]
|
||||
|
||||
# 1::[];;
|
||||
_: int list = [1]
|
||||
```
|
||||
|
||||
**The constructor is right associative `e1::e2::e3::l` => `e1::(e2::(e3::l))`**
|
||||
**Exemple :**
|
||||
```Ocaml
|
||||
# [1 ; 2; 3];;
|
||||
_: int list = [1; 2; 3]
|
||||
# 1::[2; 3];;
|
||||
_: int list = [1; 2; 3]
|
||||
# 1::2::[3];;
|
||||
_: int list = [1; 2; 3]
|
||||
# 1::2::3::[];;
|
||||
_: int list = [1; 2; 3]
|
||||
```
|
||||
|
||||
### Priority
|
||||
```Ocaml
|
||||
# 1 + 2::[];;
|
||||
_: int list = [3]
|
||||
|
||||
# 1 < 2 :: [];;
|
||||
Error: int ≠ int list
|
||||
```
|
||||
The priority is somewhere between the addition. To avoid any doubt in the code, we have to put parenthesis.
|
||||
|
||||
## Concatenation
|
||||
```Ocaml
|
||||
# let l1 = [1; 2] and l2 = [3; 4];;
|
||||
val l1: int list = [1, 2]
|
||||
val l2: int list = [3, 4]
|
||||
|
||||
# l1::l2;;
|
||||
Error: int list ≠ int
|
||||
|
||||
#l1 @ l2;;
|
||||
_: int list = [1 ; 2 ; 3; 4]
|
||||
```
|
||||
> The operator `@`is not constant
|
||||
|
||||
## List manipulation
|
||||
### Traverse
|
||||
Sequential traverse have two solution, first is the list is empty, then you stop. Else if the list is not empty, we extract the head and the tail, we treat the head and we traverse the trail (rec call)
|
||||
```Ocaml
|
||||
# let p = (1, 2);;
|
||||
val p: int*int = (1,2)
|
||||
# let (a, b) = p;;
|
||||
val a: int = 1
|
||||
val b: int = 2
|
||||
|
||||
# let l = [1; 2; 3];;
|
||||
val l : int list = [1; 2; 3]
|
||||
# let e::t = l;;
|
||||
Warning: the pattern matching is not exhausitve
|
||||
val e: int = 1
|
||||
val t: int list = [2; 3]
|
||||
# let rec length l =
|
||||
if l = [] then 0
|
||||
else
|
||||
let e::t = l in
|
||||
1 +. length t;;
|
||||
Warning : pattern matching not exhaustive
|
||||
val length: 'a list -> int = <fun>
|
||||
|
||||
# let rec length = function
|
||||
| [] -> 0
|
||||
| _::t -> 1 + length t;;
|
||||
(* with this solution there is no warning *)
|
||||
val length : 'a list -> int = <fun>
|
||||
```
|
||||
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
|
||||
A[l] --> |h::t| B[m < h ? ]
|
||||
|
||||
B --> C[m<-h]
|
||||
|
||||
B --> D[keep m]
|
||||
|
||||
A --> |"[]"| E[m]
|
||||
|
||||
C --> F[Continue the serach with t]
|
||||
|
||||
D --> F
|
||||
```
|
||||
|
||||
## Build/modify a list
|
||||
### Construction method
|
||||
```Ocaml
|
||||
# let rec what = function
|
||||
0 -> []
|
||||
| n -> n::what(n-1);;
|
||||
val what : int -> int list = <fun>
|
||||
|
||||
# what 3;;
|
||||
```
|
||||
|
||||
### Reverse
|
||||
<center><img src="https://i.imgur.com/XcYIuTX.jpg" height="300px" width="auto"/></center>
|
||||
|
||||
### Complexity
|
||||
|
||||
<center><iframe width="560" height="315" src="https://www.youtube.com/embed/KXAbAa1mieU?si=cbLGc2y64N87Rv_z" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe></center>
|
||||
|
92
Algo/B1/Courses/Chapter 7 - High Order (exercises).md
Normal file
92
Algo/B1/Courses/Chapter 7 - High Order (exercises).md
Normal file
@ -0,0 +1,92 @@
|
||||
## Ex 1.2
|
||||
```Ocaml
|
||||
# let sum n =
|
||||
if n < 0 then
|
||||
invalid_arg "n<0"
|
||||
else
|
||||
let rec sumrc n =
|
||||
if n=0 then
|
||||
0
|
||||
else
|
||||
n + sum(n-1)
|
||||
in sumrc n;;
|
||||
val sum : int -> int = <fun>
|
||||
|
||||
(*Correction*)
|
||||
let sigma f n =
|
||||
if n<0 then
|
||||
invalid_arg "n<0"
|
||||
else
|
||||
let rec sig = function
|
||||
| 0 -> f0
|
||||
| n -> fn + sig (n-1)
|
||||
in sig n;;
|
||||
val sigma: (int -> int) -> int -> int = <fun>
|
||||
```
|
||||
|
||||
## Ex 2.1
|
||||
```
|
||||
# let rec map f = function
|
||||
| [] -> []
|
||||
|e::t -> f e::map f t ;;
|
||||
val map : ('a -> 'b) -> 'a list -> 'b list = <fun>
|
||||
```
|
||||
|
||||
## Ex 2.2
|
||||
```
|
||||
# let rec for_all p = function
|
||||
| [] -> true
|
||||
| e::t -> p e && for_all p t;;
|
||||
val for_all: ('a -> bool) -> 'a list -> bool = <fun>
|
||||
```
|
||||
|
||||
## Ex 2.3
|
||||
```
|
||||
# let rec exists p = function
|
||||
| [] -> true
|
||||
| e::t -> p e || for_all p t;;
|
||||
val exists: ('a -> bool) -> 'a list -> bool = <fun>
|
||||
```
|
||||
|
||||
## Ex 2.4
|
||||
```
|
||||
# let rec find p = function
|
||||
| [] -> true
|
||||
| e::t -> if p e then e else find p t;;
|
||||
val exists: (bool -> bool) -> bool list -> bool = <fun>
|
||||
```
|
||||
|
||||
## Ex 2.5
|
||||
```Ocaml
|
||||
# let rec filter p : function
|
||||
| [] -> []
|
||||
| e::t -> if p e then
|
||||
e::filter p t
|
||||
else filter p t;;
|
||||
val filter: ('a -> bool) -> 'a list -> 'a
|
||||
```
|
||||
|
||||
## Ex 2.6
|
||||
```Ocaml
|
||||
let rec partition p l =
|
||||
match l with
|
||||
| [] -> ([], [])
|
||||
| h==t> let (l1, l2) = partition p t in
|
||||
if p h then (h::l1,l2)
|
||||
else (l1, h::l2);;
|
||||
val partition : ('a -> bool) -> 'a list -> 'a list * 'a list = <fun>
|
||||
```
|
||||
|
||||
## Ex 2.7
|
||||
```Ocaml
|
||||
# let less2 p k l1 l2 =
|
||||
if k < 0 then invalid_arg "k needs to be positive" else
|
||||
let rec less p k l1 l2 acc = match (l1, l2) with
|
||||
| ([],[]) -> acc < k
|
||||
| (e::t, e::t2) -> if p e e2 then less p k t t2 (acc + 1)
|
||||
else less p k t t2 acc
|
||||
in less p k l1 l2 0;;
|
||||
val less2 : ('a -> 'b -> bool) -> int -> 'a list -> 'b list -> bool = <fun>
|
||||
```
|
||||
## Ex 3.1
|
||||
```Ocaml
|
Reference in New Issue
Block a user