vault backup: 2023-11-13 13:50:53
66
Algo/B1/CM/CM du 04 octobre.md
Normal file
@ -0,0 +1,66 @@
|
||||
An abstract type have a signature, which contains types, uses and operations, and have some axioms.
|
||||
|
||||
An axiom let us determine the value of the application of the observers with the internal operations (in the example below, the operation modify). We can see that as a validation. An axiom must be precise. An axiom is the application of the observer on an internal operation : `observer(internal operation)`
|
||||
|
||||
```
|
||||
Types
|
||||
vector
|
||||
Uses
|
||||
integer, element
|
||||
Operations
|
||||
Modify : vector x integer x element -> vector /*internal operation*/
|
||||
Nth: vector x integer -> element /* Observers */
|
||||
Lowerlimit: vector -> integer /* Observers */
|
||||
Upperlimit: vector -> integer /* Observers */
|
||||
|
||||
Axioms
|
||||
lowerlimit(v) =< i =< upperlimit(v) -> nth(modify(v,i,e), i) = e
|
||||
```
|
||||
In this example, the axiom explain that it check nth position in the modified vector
|
||||
|
||||
The axiom can't be contradictory. Two (or more) contradictory axioms are call the consistency. When we create the axiom, we have to remove all the consistency.
|
||||
Example:
|
||||
```
|
||||
nth(v,1)=0
|
||||
nth(v,i)=i
|
||||
```
|
||||
That an consistency, because the two `nth`axioms are contradictory
|
||||
|
||||
The completeness is when we have enough axioms for our abstract type :
|
||||
1. **Completeness**: Axioms should provide a complete and unambiguous specification of the ADT's behavior. This means that they should cover all possible scenarios and outcomes for the ADT's operations. Users of the ADT should be able to rely on these axioms to understand how the ADT behaves in different situations.
|
||||
|
||||
2. **Consistency**: Axioms should be consistent with each other and with the intended behavior of the ADT. This means that the axioms should not contradict each other, and they should accurately reflect the expected behavior of the ADT's operations. Inconsistent axioms can lead to confusion and incorrect usage of the ADT.
|
||||
|
||||
|
||||
To use partial operations we have to create some preconditions
|
||||
|
||||
```
|
||||
Types
|
||||
vector
|
||||
Uses
|
||||
integer, element, boolean
|
||||
Operations
|
||||
Vect: integer x integer -> vector /* internal operation */
|
||||
Modify : vector x integer x element -> vector /*internal operation*/
|
||||
Nth: vector x integer -> element /* Observers */
|
||||
isint: vector x integer -> boolean
|
||||
Lowerlimit: vector -> integer /* Observers */
|
||||
Upperlimit: vector -> integer /* Observers */
|
||||
|
||||
Preconditions
|
||||
nth(v,i) is-defined-iaoi lowerlimit(v) =< (i) =< upperlimit(v) & isinit(v,i) = true
|
||||
|
||||
Axioms
|
||||
lowerlimit(v) =< i =< upperlimit(v) -> nth(modify(v,i,e), i) = e
|
||||
lowerlimit(v) =< i =< upperlimit(v) & lowerlimit(v) =< j =< upperlimit(v) & i≠j -> nth(modifiy(v,i,e), j) = nth(v,j)
|
||||
isinit(vect(i,j),k)= false
|
||||
lowerlimit(v) =< i =< upperlimit(v) -> isinit(modifiy(v,i,e),i)= true
|
||||
... (all the other axioms)
|
||||
```
|
||||
Here, `nth`is a partial operation and `isinit` is a auxiliary operation
|
||||
|
||||
## Important things to create a abstract type
|
||||
- What we want to create
|
||||
- Add all necessary operations
|
||||
- Preconditions
|
||||
- Axios
|
52
Algo/B1/CM/CM du 27 septembre.md
Normal file
@ -0,0 +1,52 @@
|
||||
## Outline
|
||||
- Abstract Algebraic Data types
|
||||
- Elementary types
|
||||
- List
|
||||
- Stack
|
||||
- Queue
|
||||
- Set
|
||||
- Searching algorithms
|
||||
- Tree
|
||||
- Binary
|
||||
- General
|
||||
- BST
|
||||
- AVL
|
||||
- A234
|
||||
|
||||
## Abstract Algebraic Data Types
|
||||
### Signature and hierarchy
|
||||
- a signature is composed by
|
||||
- a type (integer, stack, queue, graph)
|
||||
- an operations (name: profile)
|
||||
- Exemple:
|
||||
- ``insert: list x integer x element -> list``
|
||||
- ``insert(l, i, e)``
|
||||
- return a result of type `list`
|
||||
- We can use the `_`to pass an argument without parentheses
|
||||
- `facotrial: interger -> integer`= `_!: interger -> integer`
|
||||
- `power: integer x integer -> integer`= `_^_: integer x integer -> integer`
|
||||
- Operations
|
||||
- `0: -> integer`
|
||||
- `false: -> boolean`
|
||||
- `pi: -> real`
|
||||
- Types
|
||||
- Boolean
|
||||
- Opération:
|
||||
- `false: -> boolean`
|
||||
- `true: -> boolean`
|
||||
- `not_: boolean -> boolean`
|
||||
- `_and_: boolean x boolean -> boolean`
|
||||
- `_or_: boolean x boolean -> boolean`
|
||||
- Vectors (defined type)
|
||||
- Uses: integer and element (predefined types)
|
||||
- Operations:
|
||||
- `modify: vector x integer x element -> vector` (internal operation)
|
||||
- `nth: vector x integer -> element` (observers)
|
||||
- `lowerlimit: vector -> integer` (observers)
|
||||
- `upperlimit: vector -> integer` (observers)
|
||||
- Use
|
||||
- `nth(v, i+2)`
|
||||
> Every time that an operation return a defined type, is a **internal operation.** An internal operation will really modify the data
|
||||
|
||||
> **An observer** is when there is AT LEAST 1 defined type vector and who return a predefined type. The observer just look into the data and return the selected value, but he don't change any values.
|
||||
|
54
Algo/B1/CM/Lists.md
Normal file
@ -0,0 +1,54 @@
|
||||
List is the most fundamental data type. Is a sequencial argument, is a final sequence of element. It is no possible to have more than one element per box.
|
||||
There is two different way to declare a list, the recursive one and the iterative one.
|
||||
|
||||
## Recursive list
|
||||
- The first box is the **head of the list**
|
||||
- The rest of the list is **the tail of the list**
|
||||
- The signature of the recursive list is the following:
|
||||
```
|
||||
TYPES
|
||||
list, box
|
||||
|
||||
USES
|
||||
element
|
||||
|
||||
OPERATIONS
|
||||
emptylist : -> list (* Internal operations of list*)
|
||||
cons : element x list -> list (* Internal operations of list *)
|
||||
tail : list -> list (* Internal operations of list *)
|
||||
head : list -> box (* Internal operations of box *)
|
||||
contents : box -> element (* Observer of box *)
|
||||
first : list -> element (* Observer of list *)
|
||||
next : box -> box (* Internal operation of box *)
|
||||
|
||||
PRECONDITIONS
|
||||
tail(l) is-defined-iaoi l ≠ emptylist
|
||||
head(l) is-defined-iaoi l ≠ emptylist
|
||||
first(l) is-defined-iaoi l ≠ emptylist
|
||||
|
||||
AXIOMS
|
||||
first(_l_) = contents(head(l))
|
||||
tail(cons(_e,l_)) = l
|
||||
first(cons(_e,l_)) = e
|
||||
next(head(_l_)) = head(tail(l))
|
||||
|
||||
WITH
|
||||
list l
|
||||
element e
|
||||
```
|
||||
`cons` add en element to the head of the list (eg. li <- cons(cloud, li))
|
||||
`head`return the element in the head of the list (eg. pl <- head(li))
|
||||
`contents`return what is the element of the head
|
||||
`first`return the first element of the list (is equivalent to contents)
|
||||
`tail`remove the first element of the list (eg. fl <- tail (li))
|
||||
`next`return the element after a box (eg. pspt <= next(head(li))))
|
||||
|
||||
## Array implementation
|
||||
Let's take a list l = E ; D ; C ; B ; A. An array implementation of the list l will be:
|
||||
|
||||
|1|2|3|4|5|
|
||||
|:----:|:----:|:----:|:----:|:----:|
|
||||
|A|B|C|D|E|
|
||||
|5|
|
||||
|
||||
The first line of the table is the $n^{th}$ place of the element, the second line is all the element of the list, and the third line is the place of the first element of the list (here E is at the $5^{th}$ position).
|
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
@ -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
@ -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
|
154
Algo/B1/Séminaire/Chapter 1 - CAML basics.md
Normal file
@ -0,0 +1,154 @@
|
||||
|
||||
<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/basics-meme.png " width=auto height=400 /> </center>
|
||||
|
||||
CAML is a categorical abstract machine language. It is strongly typed. It was created by INRIA in 1984.
|
||||
|
||||
## 1.1. General idea
|
||||
It's a simple language to write.
|
||||
```Ocaml
|
||||
# 1+2 ;;
|
||||
```
|
||||
|
||||
- **#** is the prompt (we don't have to write it)
|
||||
- **1 + 2** is the program
|
||||
- **;;** is the end of the line
|
||||
|
||||
```Ocaml
|
||||
_: int=3 (*That a Caml answer to the previous program*)
|
||||
```
|
||||
|
||||
```Ocaml
|
||||
# 1+2.2;; (*That an error*)
|
||||
|
||||
# 1. +. 2.2;; (*This is good*)
|
||||
```
|
||||
## 1.2. CAML interaction
|
||||
```Ocaml
|
||||
# 1;; (*He can be a simple expression*)
|
||||
_: int=1
|
||||
|
||||
# "Hello World";; (*He can be a string*)
|
||||
_:string = "Hello World"
|
||||
```
|
||||
|
||||
The general form is :
|
||||
```Ocaml
|
||||
# expr ;;
|
||||
-: type of the evaluation = result of the evaluation
|
||||
```
|
||||
|
||||
## 1.3. Definitions
|
||||
### Global definitions
|
||||
```Ocaml
|
||||
# let x=1+2;;
|
||||
val x:int = 3 (*our current env is x -> 3*)
|
||||
|
||||
# let y=x/2;;
|
||||
val y:int = 1 (*our current env is x -> 3 ; y -> 1*)
|
||||
|
||||
# let x = 2
|
||||
val x : int = 2
|
||||
|
||||
# x;;
|
||||
_: int = 2
|
||||
|
||||
# let name = expr;;
|
||||
val name: type of evaluation
|
||||
```
|
||||
### Local definitions
|
||||
```Ocaml
|
||||
# let r = 1. in let pi = 3.14 in 2*pi*r;;
|
||||
- : float = 6.28
|
||||
|
||||
# let x = 10 in y = 2*x in x+y;;
|
||||
- : float = 30
|
||||
|
||||
# x;;
|
||||
- : int =2 (*see global definition section*)
|
||||
|
||||
# pi;;
|
||||
error: unbound value pi
|
||||
```
|
||||
|
||||
when there is the keyword ``len``and ``in`` that create a local definition. A local definition is something that only exist in our expression and then it disappear. You can define a local definition into a variable : `` let x = let r = 1. in let pi = 3.14 in 2*pi*r;;`` (for example)
|
||||
|
||||
### Multiple definitions
|
||||
```Ocaml
|
||||
# let r = 1. and pi = 3.14 in 2 *. pi *. r;; (*local version*)
|
||||
- : float = 6.28
|
||||
|
||||
# let x = 1.2 and y = "Hello";;
|
||||
val x: float = 1.2 (*our current env is x -> 3 ; y -> 1 ; x -> 1.2 *)
|
||||
val y: string = "Hello" (*our current env is x -> 3 ; y -> 1 ; x -> 1.2 ; y -> "Hello"*)
|
||||
# let x = 2 and y = x + 1 in y + 2;;
|
||||
Error (*because x is 1.2 in our current evaluation*)
|
||||
```
|
||||
> ⚠️ We have only one `let` and one `in` for the multiple definitions methods
|
||||
|
||||
## 1.4 Basic types
|
||||
- Integer: ``int``
|
||||
- Compatible operator : + ; - ; * ; / ; mod
|
||||
- Same operator priority than in mathematics
|
||||
```Ocaml
|
||||
# 2+3*2;;
|
||||
_: int = 8
|
||||
|
||||
# (2+3)*3;;
|
||||
_: int = 10
|
||||
|
||||
# max_int 1 073 741 823
|
||||
_: int = 2^30-1
|
||||
|
||||
# max_int -1 073 741 824
|
||||
_: int = -2^30
|
||||
```
|
||||
- Float: ``float``
|
||||
- Compatible operator : -. ; +. ; * . ; /.
|
||||
- Booleans: ``bool``
|
||||
- Can be ``true``or ``false``
|
||||
```Ocaml
|
||||
# let x = 2 and y = 1 in x/y > 1;;
|
||||
_: bool = true
|
||||
|
||||
# let x = 2 and y = 0 in x/y > 1;;
|
||||
Exception: Division by zero
|
||||
|
||||
# let x = 2 and y = 0 in y<>0 && x/y> 1;;
|
||||
_: bool = false
|
||||
```
|
||||
|
||||
|
||||
- Char: `char`
|
||||
- 8 bits -> extended ASCII table
|
||||
```Ocaml
|
||||
# 'a'= 'A';;
|
||||
_: bool = false
|
||||
|
||||
# 'a'
|
||||
- : char = 'a'
|
||||
```
|
||||
|
||||
- String: `string`
|
||||
```Ocaml
|
||||
# "ab" < "abc" ;;
|
||||
_: bool = true (*because O chars -> 2^24 - 6 chars*)
|
||||
|
||||
# "Hello" ^" World"
|
||||
_: string = "Hello World"
|
||||
|
||||
# "abc".[1]
|
||||
_: char = "b"
|
||||
```
|
||||
⚠️ Les minuscules passent avant les majuscules
|
||||
|
||||
### Comparaison
|
||||
|
||||
|Mathematics|$=$|$\not=$|$<$|$>$|$\eqslantgtr$|$\eqslantless$|
|
||||
|:----:|:----:|:----:|:----:|:----:|:----:|
|
||||
|CAML|`=`|`<>`|`<`|`>`|`<=`|`>=`|
|
||||
|
||||
|CAML|Maths|English|
|
||||
|:-----|:-----|:-----|
|
||||
|not|$\neg$|negation|
|
||||
|&&|$\land$|and|
|
||||
|// (vertical bar)|$\lor$|or (inclusive)|
|
96
Algo/B1/Séminaire/Chapter 2 - Functions.md
Normal file
@ -0,0 +1,96 @@
|
||||
|
||||
<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/functions-meme.jpg " width=auto height=400 /> </center>
|
||||
|
||||
|
||||
## 2.1. One parameter function
|
||||
```Ocaml
|
||||
# let successor x=x+1;;
|
||||
val successor: int -> int =<fun>
|
||||
|
||||
# successor;;
|
||||
_ : int -> int =<fun>
|
||||
|
||||
# successor 3;;
|
||||
_: int = 4
|
||||
|
||||
# successor (-1)::
|
||||
_: int = 0
|
||||
```
|
||||
|
||||
>`x` is call a formal parameter and `x+1` is call the body of the function. `3` is an effective parameter (= argument). For the last line, the paratheses are needed, without it, CAML will return an error
|
||||
|
||||
|
||||
#### ⚠️ ``f x = f(x)`` and ``fx+gy = (fx)+(gy)
|
||||
|
||||
```Ocaml
|
||||
# let f x = x+1 and g x = x*2
|
||||
val f: int -> int = <fun>
|
||||
val g: int -> int = <fun>
|
||||
|
||||
# fg 3;;
|
||||
Error: was expecting an integer and get a function
|
||||
# f(g 3);; (*This way there is no error*)
|
||||
_: int = 7
|
||||
```
|
||||
|
||||
```Ocaml
|
||||
# let successor_of_double x=f(gx);;
|
||||
val successor_of_double: int -> int = <fun>
|
||||
|
||||
# successor_of_double (-12);;
|
||||
_: int = -23
|
||||
```
|
||||
|
||||
#### Existing functions
|
||||
```Ocaml
|
||||
# sqrt;;
|
||||
_: float -> float =<fun>
|
||||
|
||||
# int_of_float;;
|
||||
_: float -> int =<fun>
|
||||
|
||||
# length "toto" ;;
|
||||
Error : Unboud
|
||||
# String.lenght "toto";; (*String is a library*)
|
||||
_: int = 4
|
||||
```
|
||||
|
||||
|
||||
## 2.2. Functions and local definitions
|
||||
```Ocaml
|
||||
# let pred x = x - 1 in pred 3 + pred 4;;
|
||||
_: int = 6
|
||||
|
||||
# pred;;
|
||||
Error
|
||||
|
||||
# let square_of_pred x = let pred_x = x - 1 in pred_x * pred_x;;
|
||||
val square_of_pred: int -> int = <fun>
|
||||
|
||||
# square_of_pred 3;;
|
||||
_: int = 4
|
||||
|
||||
# let square_of_pred x = let pred x = x - 1 in pred x * pred x
|
||||
val square_of_pred: int -> int = <fun>
|
||||
val pred: int -> int = <fun>
|
||||
|
||||
# square_of_pred 3;;
|
||||
_: int = 4 (*same things but with another method*)
|
||||
```
|
||||
|
||||
## 2.3. Function with several parameters (2 or more)
|
||||
|
||||
```Ocaml
|
||||
(*The logic way (for us)*)
|
||||
# let average(a,b) = (a+b)/2 ;;
|
||||
val average: int*int -> int = <fun>
|
||||
|
||||
(*This method is not for several parameter, is just a one parameter wich is a couple*) (*f(x,y) ≠ f x y*)
|
||||
|
||||
(*The OCaml way (the way that it work) *)
|
||||
# let average a b = (a+b)/2;;
|
||||
val average: int -> int -> int = <fun>
|
||||
# average (-2) (2);;
|
||||
-: int = 0
|
||||
```
|
||||
|
187
Algo/B1/Séminaire/Chapter 3 - Case analysis.md
Normal file
@ -0,0 +1,187 @@
|
||||
## 3.1. The alternative
|
||||
|
||||
<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/if-meme.png" width=auto height=400 /> </center>
|
||||
|
||||
### The if structure
|
||||
```Ocaml
|
||||
if cond then expr1 else expr2
|
||||
```
|
||||
> ⚠️ `expr1` and `expr2` have to be the same type. `cond` is a `bool`
|
||||
|
||||
**For exemple**
|
||||
```Ocaml
|
||||
# if 1<2 then "higher" else "lower" ;;
|
||||
-: string = "higher"
|
||||
```
|
||||
|
||||
**Exercise : absolute program**
|
||||
```Ocaml
|
||||
# let abs(x) =
|
||||
if x>0 then x
|
||||
else -x ;;;
|
||||
val abs : int -> int <fun>
|
||||
```
|
||||
|
||||
## 3.2. Exceptions
|
||||
|
||||
|
||||
<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/exception-meme.png" width=auto height=400 /> </center>
|
||||
|
||||
### Division by 0:
|
||||
```Ocaml
|
||||
# 1/0
|
||||
Exception : Division by zero
|
||||
```
|
||||
|
||||
### Failwith:
|
||||
Failwith is a function that take a string argument (the reason) and return the error. That way, we can raise an error into our code
|
||||
```Ocaml
|
||||
# failwith;;
|
||||
-: string -> a' = <fun>
|
||||
|
||||
# failwith "oops";;
|
||||
Exception : Failwith "oops"
|
||||
```
|
||||
|
||||
### invalid_arg:
|
||||
Invalid_arg is a function that take a string argument (the reason) and return the error. That way, we can raison an error about an argument
|
||||
```Ocaml
|
||||
# invalid_arg "oops";
|
||||
Exception: Invalid_argument "oops"
|
||||
|
||||
(*example*)
|
||||
# let div a b =
|
||||
if b = 0 then invalid_arg("div: b = 0")
|
||||
else a/b ;;;
|
||||
val div int -> int -> int = <fun>
|
||||
```
|
||||
|
||||
## 3.3. Filtering
|
||||
|
||||
|
||||
<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/filter-meme.png " width=auto height=400 /> </center>
|
||||
|
||||
### Explicit filtering
|
||||
|
||||
> Explicit means that you matches the value
|
||||
|
||||
|
||||
**General syntax**
|
||||
|
||||
```Ocaml
|
||||
match expr with pattern1 -> result1 | pattern2 -> result2 | ... | patternn -> resultn
|
||||
```
|
||||
> All expressions and pattern must avec the same type
|
||||
|
||||
**Example**
|
||||
```Ocaml
|
||||
# let f x = match x with
|
||||
0 -> 18
|
||||
| 1 -> 24
|
||||
| y -> y * y;;
|
||||
|
||||
val f : int -> int = <fun>
|
||||
|
||||
# f 1;;
|
||||
- : int = 24
|
||||
|
||||
# let g x = match x with
|
||||
0 -> 18
|
||||
| y -> y + y (*here will return a warning : unused case*)
|
||||
| 1 -> 24 ;;
|
||||
|
||||
val f : int -> int = <fun>
|
||||
# f 1;;
|
||||
- : int = 1
|
||||
|
||||
# let d x = match x with
|
||||
0 -> 18;
|
||||
| 1 -> 24;;
|
||||
(* Warning = pattern matching not exhaustive *)
|
||||
```
|
||||
|
||||
### Filtering several values
|
||||
|
||||
```Ocaml
|
||||
# let and_ a b =
|
||||
match a with
|
||||
true -> (match b with
|
||||
true -> true
|
||||
| false -> false)
|
||||
| false -> false;;
|
||||
```
|
||||
|
||||
> ⚠️ If you forgot the parentheses, Caml will belived the two `|false` belong to the same pattern matching
|
||||
|
||||
### Universal pattern
|
||||
```Ocaml
|
||||
# let f x = match x with
|
||||
0 -> 18
|
||||
| 1 -> 24
|
||||
| _ -> x*x ;;
|
||||
```
|
||||
|
||||
### "Or" filter
|
||||
```Ocaml
|
||||
# let f x match x with
|
||||
0 | 20 -> 18
|
||||
| 1 | 11 | 12 -> 24
|
||||
|_ -> x * x ;;
|
||||
```
|
||||
|
||||
### Guarded filters
|
||||
```Ocaml
|
||||
# let sign x = match x with
|
||||
0 -> 0
|
||||
| y when y < 0 -> -1
|
||||
| _ -> 1
|
||||
```
|
||||
|
||||
> `y when y<0` is an evaluation
|
||||
### Filtering and anonymous functions
|
||||
```Ocaml
|
||||
# let succ x = x +1;;
|
||||
val succ: int -> int = <fun>
|
||||
|
||||
(* these two functions are equivalent *)
|
||||
|
||||
# let succ = function x -> x + 1;;
|
||||
val succ: int -> int = <fun>
|
||||
```
|
||||
|
||||
```Ocaml
|
||||
# let f x = expr (*is equal to *) let f = function x -> expr
|
||||
```
|
||||
> ⚠️ Learn by heart
|
||||
|
||||
**Exemple with `avg` function**
|
||||
```Ocaml
|
||||
# let avg = function a -> function b -> (a+b)/2
|
||||
val avg : int -> int -> int = <fun>
|
||||
```
|
||||
> 💭 We read that like "let avg the function that to a associate the function that to b associate a+b divided by two"
|
||||
|
||||
**For the match function**
|
||||
```Ocaml
|
||||
# let f x = match x with
|
||||
| 0 -> 18
|
||||
| 1 -> 24
|
||||
| _ -> x*x ;;
|
||||
# let f = function
|
||||
| 0 -> 18
|
||||
| 1 -> 24
|
||||
| _ -> x * x;;
|
||||
```
|
||||
|
||||
### Filtering several values
|
||||
```Ocaml
|
||||
# let and_p a b = match (a,b) with
|
||||
| (true, true) -> true
|
||||
| _ -> false;;
|
||||
val and_p : bool -> bool -> bool = <fun>
|
||||
|
||||
# let and_t = function
|
||||
| (true, true) -> true
|
||||
| _ -> false
|
||||
val and_t -> bool * bool = <fun>
|
||||
```
|
92
Algo/B1/Séminaire/Chapter 4 - A bit of imperative.md
Normal file
@ -0,0 +1,92 @@
|
||||
|
||||
<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/unitaire-meme.png " width=auto height=400 /> </center>
|
||||
|
||||
|
||||
## 0.1. Print
|
||||
If we want to print something in CAML, we have to use this structure
|
||||
|
||||
```Ocaml
|
||||
# print_string "Hello World!";;
|
||||
Hello! - : unit=()
|
||||
|
||||
# print_int ;;
|
||||
-: int -> unit = <fun>
|
||||
|
||||
(*expression*)
|
||||
# print_[type] [things to print];;
|
||||
[things to print] -: unit=()
|
||||
```
|
||||
|
||||
**Difference between compiler and interpreter for print**
|
||||
```mermaid
|
||||
flowchart LR
|
||||
|
||||
A[CAML] -- compile --> B[ ] -- exec --> C[standard output] & D[standard error] ~~~ E(on your terminal)
|
||||
```
|
||||
```mermaid
|
||||
flowchart LR
|
||||
|
||||
A[CAML] -- interpreter --> B[standard error] & C[standard output] & D[CAML answer] ~~~ E(in the interpreter interface)
|
||||
```
|
||||
|
||||
**To print something and create a new line for the CAML evaluation**
|
||||
```Ocaml
|
||||
# print_endline "toto";;
|
||||
toto
|
||||
-: unit = ()
|
||||
```
|
||||
**To just print a newline**
|
||||
```Ocaml
|
||||
# print_newline();;
|
||||
-: unit = ()
|
||||
|
||||
(* example *)
|
||||
# print_newline(print_int 54);;
|
||||
54
|
||||
-: unit = ()
|
||||
```
|
||||
|
||||
## 0.2. Sequence of prints
|
||||
To print two things on the same line we have to use this structure
|
||||
```Ocaml
|
||||
# print_string "The answer is: "; print_int 42;;
|
||||
The answer is: 42 -: unit = ()
|
||||
|
||||
# 3*2*7; print_string "The answer is : ";;
|
||||
The answer is -: unit = ()
|
||||
Warning 10 [non-unit-statement]: this expression should have type unit.
|
||||
|
||||
# print_string "The answer is: "; 3*2*7;;
|
||||
The answer is: -:int = 42
|
||||
```
|
||||
|
||||
### 0.3. Print in a function
|
||||
```OCaml
|
||||
# let print_even n =
|
||||
if n mod 2 = 0 then
|
||||
print_int n;;
|
||||
(*Caml will automaticaly add the else with a empty value ()*)
|
||||
val print_even: int -> unit = <fun>
|
||||
|
||||
# print_even 4;;
|
||||
4 -: unit = ()
|
||||
|
||||
# print_even 7;;
|
||||
-: unit = ()
|
||||
|
||||
# let ret_even n =
|
||||
if n mod 2 = 0 then
|
||||
n;;
|
||||
Error: should have int type (*because of the hidden else*)
|
||||
|
||||
# let print_even n =
|
||||
if n mod 2 = 0 then
|
||||
begin
|
||||
print_int n ;
|
||||
print_newline()
|
||||
end;; (*begin and end used to execute more than 1 function into a if*)
|
||||
val print_even : int -> unit = <fun>
|
||||
|
||||
# print_even 4;;
|
||||
4
|
||||
-: unit = ()
|
153
Algo/B1/Séminaire/Chapter 5 - Recursivity.md
Normal file
@ -0,0 +1,153 @@
|
||||
|
||||
<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/recursivite-meme.png " width=512 height=auto /> </center>
|
||||
|
||||
### 5.1. Simple functions
|
||||
To create a recursive function we have to use this structure
|
||||
|
||||
```Ocaml
|
||||
(*normal function*)
|
||||
# let f = expr -> 1) evaluate expr ; 2) create & link f to the result
|
||||
|
||||
(*recursiv function*)
|
||||
# let rec f = expr -> 1) create f ; 2) evaluate expr ; 3) link f to the result
|
||||
```
|
||||
|
||||
**Exmple with factorial function**
|
||||
```Ocaml
|
||||
# let rec fact = function
|
||||
| 0 -> 1
|
||||
| n -> n * fact(n-1)
|
||||
|
||||
# fact 4;;
|
||||
-: int = 24
|
||||
```
|
||||

|
||||
> ⚠️ CAML have a call stack limite (it will block with stack overflow if the limit is reach)
|
||||
|
||||
**Basic expression**
|
||||
```Ocaml
|
||||
let rec f params =
|
||||
if stop condition then
|
||||
stop expression
|
||||
else
|
||||
recursive expression
|
||||
```
|
||||
|
||||
To write a recurvise function we need two things
|
||||
1) There always is a stop case
|
||||
2) The parameters of a recursive call are different then its parent call, and go towards the stop condition
|
||||
|
||||
### 5.2. Down
|
||||
```Ocaml
|
||||
# let rec countdown n =
|
||||
if n < 0 then
|
||||
()
|
||||
else
|
||||
begin
|
||||
print_int n ;
|
||||
print_newline();
|
||||
countdown(n-1);
|
||||
end;;
|
||||
val countdown = int -> unit = ()
|
||||
|
||||
# countdown 3;;
|
||||
3
|
||||
2
|
||||
1
|
||||
- : unit = ()
|
||||
```
|
||||
Flowchart of CAML evaluation
|
||||
```mermaid
|
||||
flowchart LR
|
||||
|
||||
A[ctd 3] --> B[ctd 2] --> C[ctd 1] --> D[ctd 0] --> E[ctd -1] --> F[ ] --> E --> D --> C --> B --> A
|
||||
```
|
||||
> ctd is countdown
|
||||
|
||||
## 5.3. Several recursive calls
|
||||
A function that have several recursive calls is defined like this
|
||||
$$
|
||||
Fn = {1 -> \text{if } n\eqslantless{1} \brace{Fn+1+Fn+2} }
|
||||
$$
|
||||
**Fibonacci functions**
|
||||
```Ocaml
|
||||
let rec fibonacci n =
|
||||
if n = 0 then
|
||||
0
|
||||
else if n = 1 then
|
||||
1
|
||||
else
|
||||
fibonacci(n-1) + fibonacci(n-2);;
|
||||
|
||||
let rec odd n =
|
||||
if n = 0 then
|
||||
false
|
||||
else
|
||||
even (n-1);;
|
||||
|
||||
and even n =
|
||||
if n = 0 then
|
||||
true
|
||||
else
|
||||
add (n-1);;
|
||||
val add : int -> bool = <fun>
|
||||
val even : int -> bool = <fun>
|
||||
```
|
||||
|
||||
An accumulator is a variable used to stock temporary the intermediaries results of a recursive operation. In CAML the syntax for the accumulator (`inv`) is: (exemple with reverse_int exercise. See 4.9 - b)
|
||||
```Ocaml
|
||||
# let reverse_int =
|
||||
let rec rev inv = function
|
||||
| 0 -> inv
|
||||
| n -> rev (inv*10 + n mod 10)(n/10)
|
||||
in rev 0 n;;
|
||||
```
|
||||
|
||||
## 4.3. Complexity
|
||||
Exemple with egypt (4.10) vs multiply (4.6):
|
||||
```Ocaml
|
||||
# let multiply a b =
|
||||
let (a,b) = if a > b then
|
||||
(a,b) else
|
||||
(b,a)
|
||||
in let rec mult = function
|
||||
| 0 -> 0
|
||||
| b -> a +mult (b-1)
|
||||
in mult b;;
|
||||
```
|
||||
|
||||
The best algorithm in term of complexity is the parameter that is constant/linear or logarithmic. If you have an exponential algorithm, you can put it in trash :)
|
||||
|
||||
**Exemple with fibonacci algorithm**
|
||||
```Ocaml
|
||||
# let rec fibo = function
|
||||
0|1 -> 1
|
||||
| n -> fibo (n-1) + fibo(n-2);;
|
||||
```
|
||||
|
||||
|
||||
| |res|how (for human) ?|How (for function) ?|
|
||||
|:----:|:----:|:----:|:----:|
|
||||
|0|1|def|1 call|
|
||||
|1|1|def|1 call|
|
||||
|2|2|+|3 calls|
|
||||
|3|3|+|5 calls|
|
||||
|4|5|+|9 calls|
|
||||
|5|8|+|15 calls|
|
||||
|6|13|+|14 calls|
|
||||
| | |$0(n)$|$O(2^n)$|
|
||||
|
||||
|
||||
<center><img src="https://imgur.com/6OWREOm.png" height=400 width=auto/></center>
|
||||
|
||||
This function is not optimize because the number of calls is growing exponentially.
|
||||
A good function will be:
|
||||
```Ocaml
|
||||
# let fibo n =
|
||||
let rec fib i fi fi_1 =
|
||||
if n <= i then
|
||||
fi
|
||||
else
|
||||
fib (i+1)(fi+fi_1)fi
|
||||
in fib 1 1 1
|
||||
```
|
553
Algo/B1/Séminaire/Exercices seminaire.md
Normal file
@ -0,0 +1,553 @@
|
||||
|
||||
## Exercise 2.2 (Power)
|
||||
|
||||
```Ocaml
|
||||
(*First version ; 6 multiplications*)
|
||||
# let power28(x) =
|
||||
let x2 = x + x in
|
||||
let x4 = x2*x2 in
|
||||
let x8 = x4*x4 in
|
||||
let x16 = x8*x8 in
|
||||
x16*x8*x4 ;;
|
||||
|
||||
(*Second version ; 27 multiplications*)
|
||||
# let power28(x) = x*x*x*x*x*x...*x ;;
|
||||
|
||||
(*Third version ; 11 multiplications*)
|
||||
# let power28(x) =
|
||||
let sq(x) = x*x in
|
||||
let pow4(x) = sq(sq(x)) in
|
||||
pow4(pow4(x))*sq(pow4(x))*pow4(x);;
|
||||
|
||||
(*Fourth version ; 7 multiplications*)
|
||||
# let power28(x)=
|
||||
let sq(x) = x+x in
|
||||
let p4=sq(sq(x)) in
|
||||
sq(sq(p4))*sq(p4)*p4;;
|
||||
```
|
||||
|
||||
## Exercise 2.3
|
||||
|
||||
```Ocaml
|
||||
# (*my verison*)
|
||||
# let mirror(n) = let diz = n/10 and uni = n mod 10 in uni*10 + diz;;
|
||||
val mirror : int -> int = <fun>
|
||||
|
||||
# (*teatcher version*)
|
||||
# let mirror n = 10 *(n mod 10)+n/10;;
|
||||
val mirror : int -> int = <fun>
|
||||
```
|
||||
|
||||
```Ocaml
|
||||
# let abba(n) = n*100 + mirror(n) ;;
|
||||
val abba: int -> int = <fun>
|
||||
```
|
||||
|
||||
```Ocaml
|
||||
# let stammer(n) = abba(mirror(n)) * 10 000 + abba(n) ;;
|
||||
val stammer: int -> int = <fun>
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Exercice 2.6
|
||||
```Ocaml
|
||||
let sec_of_time h m s =
|
||||
h*3600 + m*60 + s ;;
|
||||
|
||||
let time_of_sec s =
|
||||
let hours = s/3600 in let minutes = (s - hours*3600)/60 in let seconds = s - hours *3600 - minutes * 60 in (hours, minutes, seconds);;
|
||||
|
||||
let add_times h1 m1 s1 h2 m2 s2 =
|
||||
let sec1 = sec_of_time h1 m1 s1 and sec2 = sec_of_time h2 m2 s2 in let resultsec = sec1 + sec2 in time_of_sec resultsec ;;
|
||||
|
||||
```
|
||||
|
||||
## Exercise 3.1
|
||||
```Ocaml
|
||||
let add a b =
|
||||
if a > b then
|
||||
a-b + a/b
|
||||
else
|
||||
b-a + b/a
|
||||
|
||||
let test x y = (if x> y then x else y ) *(x+y);;
|
||||
|
||||
|
||||
let f a b c =
|
||||
let g x y = (x+y)*(x-y) in
|
||||
if a > b then
|
||||
if b > c then (a+b)*(a-b) else (c+a) *(a-c)
|
||||
else
|
||||
if a > c then (a+b)*(a-b) else (b+c) * (b-c);;
|
||||
|
||||
let f a b c =
|
||||
(if a > b && if b > c then
|
||||
a + b else c + a
|
||||
else if a > c then a + b else b + c)*
|
||||
(if a > b && b > c then
|
||||
a - b else a - c
|
||||
else if a > c then a-b else b-c);;
|
||||
```
|
||||
|
||||
### Exercise 3.2
|
||||
```OCaml
|
||||
(*logical and*)
|
||||
# let and_if a b =
|
||||
if a then
|
||||
b
|
||||
else false;;
|
||||
val and_if: bool -> bool -> bool = <fun>
|
||||
|
||||
(*logical or*)
|
||||
# let or_if a b =
|
||||
if a then true
|
||||
else b;;
|
||||
|
||||
val or_if: bool -> bool -> bool = <fun>
|
||||
|
||||
|
||||
(*logical implication*)
|
||||
# let imply_if a b =
|
||||
if a then b
|
||||
else true;;
|
||||
val imply_if: bool -> bool -> bool = <fun>
|
||||
|
||||
(*logical exclusive or*)
|
||||
let xor a b =
|
||||
if a then
|
||||
if b then false else true
|
||||
else
|
||||
if b then true else false
|
||||
|
||||
(*logical equivalence = a b*)
|
||||
let equiv a b =
|
||||
if a then b
|
||||
else
|
||||
if b then false else true (*not b*)
|
||||
|
||||
```
|
||||
|
||||
### Exercise 3.3
|
||||
```Ocaml
|
||||
# let max2 number1 number2 = if number1 > number2 then number1 else number2
|
||||
val max2 : 'a -> 'a -> 'a = <fun>
|
||||
|
||||
# let min2 number1 number2 = if number1 > number2 then number2 else number1
|
||||
val min2 : 'a -> 'a -> 'a = <fun>
|
||||
|
||||
# let max3 x y z =
|
||||
let high = if x > y then x else y in
|
||||
if high > z then
|
||||
high
|
||||
else z;;
|
||||
val max3 : 'a -> 'a -> 'a -> 'a = <fun>
|
||||
|
||||
# let min3 x y z =
|
||||
let low = if x < y then x else y in
|
||||
if low < z then
|
||||
low
|
||||
else z;;
|
||||
val min3 : 'a -> 'a -> 'a -> 'a = <fun>
|
||||
|
||||
# let middle3 x y z =
|
||||
x + y + z - min3 x y z - max x y z ;;
|
||||
val middle3 = int -> int -> int = <fun>
|
||||
|
||||
#let max4 number1 number2 number3 number4 =
|
||||
let nb1 = max2(number1 number2) and nb2 = max2(number3 number4) in max2(nb1 nb2)
|
||||
|
||||
# let max4 x y z t= max2(max2 x y)(max2 z t)
|
||||
val max4 : 'a -> 'a -> 'a -> 'a -> 'a = <fun>
|
||||
# let min4 x y z t= min2(min2 x y)(min2 z t)
|
||||
|
||||
```
|
||||
### Exercise 3.4
|
||||
```Ocaml
|
||||
let highest_square_sum x y z =
|
||||
let sq x = x*x in
|
||||
sq(max3 x y z) + sq(middle3 x y z)
|
||||
val highest_square_sum : int -> int -> int -> int = <fun>
|
||||
|
||||
```
|
||||
|
||||
## Exercise 3.7
|
||||
```Ocaml
|
||||
# let rate_eco kg = match kg with
|
||||
x when x <= 500 -> 3.40
|
||||
| x when x <=1000 -> 4.60
|
||||
| x when x <= 2000 -> 5.10
|
||||
| x when x <= 3000 -> 6.90
|
||||
| _ -> invalid_arg "Cannot be more than 3000g";;
|
||||
val rate_eco : int -> float = <fun>
|
||||
|
||||
# let rate_standard kg = match kg with
|
||||
x when x <= 500 -> 4.60
|
||||
| x when x <=1000 -> 5.90
|
||||
| x when x <= 2000 -> 6.50
|
||||
| x when x <= 3000 -> 7.20
|
||||
| _ -> invalid_arg "Cannot be more than 3000g";;
|
||||
val rate_standart : int -> float = <fun>
|
||||
|
||||
# let rate_express kg = match kg with
|
||||
x when x <= 500 -> 9.10
|
||||
| x when x <=1000 -> 11.
|
||||
| x when x <= 2000 -> 13.5
|
||||
| x when x <= 3000 -> 14.2;
|
||||
| _ -> invalid_arg "Cannot be more than 3000g";;
|
||||
val rate_express : int -> float = <fun>
|
||||
|
||||
# let rate rt kg = match rt with
|
||||
| ^x when x = "economic" -> rate_eco(kg)
|
||||
| x when x = "standard" -> rate_standard(kg)
|
||||
| x when x = "express" -> rate_express(kg)
|
||||
| _ -> invalid_arg "Bad type of shipping class";;
|
||||
val rate : string -> int -> float = <fun>
|
||||
|
||||
(*4th question*)
|
||||
let price w (p1, p2, p3, p4) =
|
||||
if w <=500 then p1
|
||||
else if w <=1000 then p2
|
||||
else if w <=2000 then p3
|
||||
else if w <=3000 then p4
|
||||
else failwith "Too heavy";;
|
||||
val price = int -> 'a * 'a * 'a * 'a -> 'a = <fun>
|
||||
```
|
||||
|
||||
## Exercise 3.9
|
||||
```Ocaml
|
||||
let apm = function
|
||||
| (0, 0) -> 2
|
||||
| (0, y) -> 1
|
||||
| (x, 0) -> 1
|
||||
| (x, y) -> 0
|
||||
| _ -> invalid_arg "Error";;
|
||||
val amp: int*int -> int = <fun>
|
||||
|
||||
let strange = function
|
||||
| (0, n) -> 0
|
||||
| (m, 0) -> 2*m
|
||||
| (m, n) -> m*n ;;
|
||||
val strange: int*int -> int = <fun>
|
||||
|
||||
let or3 = function
|
||||
| (true, _, _) -> true
|
||||
| (_, true, _) -> true
|
||||
| (_, _, true) -> true
|
||||
| _ -> false
|
||||
val or3: bool*bool*bool -> bool = <fun>
|
||||
|
||||
let or3-simple = function
|
||||
| (false, false, false) -> false
|
||||
| _ -> true
|
||||
val or3-simple: bool*bool*bool -> bool = <fun>
|
||||
```
|
||||
|
||||
### Exercise 3.10
|
||||
```Ocaml
|
||||
let time_difference (d1, md1, sd1, pos1) (d2, md2, sd2, pos2)
|
||||
```
|
||||
|
||||
## Exercise 4.2
|
||||
```Ocaml
|
||||
let rec sequence = function
|
||||
| 0 -> 1
|
||||
| n -> 4* sequence(n-1) - 1;;
|
||||
val sequence : int -> int = <fun>
|
||||
```
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
|
||||
A[seq 3] --> B[4*seq2-1] --> C[4*seq1-1] --> D[4*seq0-1] --> E[1] --> F[4*1-1] --> G[4*3-1] --> H[4*11-1]
|
||||
```
|
||||
|
||||
## Exercise 4.3
|
||||
```Ocaml
|
||||
# let geometric n u0 q =
|
||||
let rec geo = function
|
||||
| 0 -> u0
|
||||
|n -> q*geo(n-1) in geo n;;
|
||||
```
|
||||
## Exercise 4.4
|
||||
```Ocaml
|
||||
# let rec gcd a b =
|
||||
if a mod b = 0 then
|
||||
b
|
||||
else
|
||||
gcd b (a mod b);;
|
||||
```
|
||||
## Exercise 4.5
|
||||
```Ocaml
|
||||
let rec add a = function
|
||||
| 0 -> a
|
||||
| b -> 1 + add a (b-1);;
|
||||
```
|
||||
|
||||
## Exercise 4.6
|
||||
```Ocaml
|
||||
let rec mult a b =
|
||||
if a = 0 || b = 0 then
|
||||
0
|
||||
else if b > 0 then
|
||||
a + mult a (b - 1)
|
||||
else
|
||||
-mult a (-b) ;;
|
||||
```
|
||||
|
||||
## Exercise 4.7
|
||||
```Ocaml
|
||||
let rec quo a b =
|
||||
if a < b || b = 0 then
|
||||
0
|
||||
else if b = 1 then
|
||||
a
|
||||
else
|
||||
1 + quo (a-b) b ;;
|
||||
```
|
||||
|
||||
## Exercise 4.9
|
||||
```Ocaml
|
||||
let rec reverse n =
|
||||
let str_n = string_of_int n in
|
||||
let len = String.length str_n in
|
||||
let rec reverse_helper index =
|
||||
if index < 0 then
|
||||
""
|
||||
else
|
||||
String.make 1 str_n.[index] ^ reverse_helper (index - 1)
|
||||
in
|
||||
reverse_helper (len - 1) ;;
|
||||
|
||||
let rec reverse_int n =
|
||||
let rec reverse_helper acc remaining =
|
||||
if remaining = 0 then
|
||||
acc
|
||||
else
|
||||
let last_digit = remaining mod 10 in
|
||||
let new_acc = acc * 10 + last_digit in
|
||||
let new_remaining = remaining / 10
|
||||
in reverse_helper new_acc new_remaining in reverse_helper 0 n ;;
|
||||
|
||||
```
|
||||
|
||||
## Exercise 4.9 - Correction
|
||||
```Ocaml
|
||||
# let reverse = function
|
||||
| 0 -> " "
|
||||
| n -> string_of_int(n mod 10) ^ reverse(n/10);;
|
||||
val reverse : int -> string = <fun>
|
||||
|
||||
# let reverse_int =
|
||||
let rec rev inv = function
|
||||
| 0 -> inv
|
||||
| n -> rev (inv*10 + n mod 10)(n/10)
|
||||
in rev 0 n;;
|
||||
```
|
||||
|
||||
## Exercise 4.10
|
||||
|
||||
```Ocaml
|
||||
let rec multiply x y =
|
||||
if x = 0 || y = 0 then
|
||||
0
|
||||
else if x mod 2 = 0 then
|
||||
multiply (x / 2) (y * 2)
|
||||
else
|
||||
y + multiply (x / 2) (y * 2)
|
||||
|
||||
(*correction*)
|
||||
# let egypt a b =
|
||||
let (a, b) = if a > b then (a,b) else (b,a) in
|
||||
let rec eg = function
|
||||
| 0 -> 0
|
||||
| b -> 2*eg(b/2) + (if b mod 2 = 0 then 0 else a)
|
||||
in
|
||||
eg b;;
|
||||
|
||||
```
|
||||
|
||||
## Exercise 4.11
|
||||
```Ocaml
|
||||
let rec puissance x n =
|
||||
if n = 0 then
|
||||
1
|
||||
else
|
||||
x*puissance x (n-1);;
|
||||
|
||||
let rec puissance_better x n =
|
||||
if n = 0 then
|
||||
1
|
||||
else if n mod 2 = 0 then
|
||||
let pb = puissance_better x (n/2) in pb*pb
|
||||
else
|
||||
let pb_odd = puissance_better x (n/2) * n in pb_odd*pb_odd;;
|
||||
|
||||
(*Correction v1*)
|
||||
let power x n = match n with
|
||||
| 0 -> (match x with
|
||||
| 0. -> failwith "power 0^0 impossible"
|
||||
| _ -> 1.)
|
||||
| _ -> (match x with
|
||||
| 1. -> 1.
|
||||
| 0. -> 0.
|
||||
| -1. -> if n mod 2 = 0 then 1. else -1.)
|
||||
| _ -> (let rec p = function
|
||||
| 0 -> 1.
|
||||
| n -> x*.p(n-1) in p n)
|
||||
;;
|
||||
|
||||
(*Correction v2*)
|
||||
let power x n = match n with
|
||||
| 0 -> (match x with
|
||||
| 0. -> failwith "power 0^0 impossible"
|
||||
| _ -> 1.)
|
||||
| _ -> (match x with
|
||||
| 1. -> 1.
|
||||
| 0. -> 0.
|
||||
| -1. -> if n mod 2 = 0 then 1. else -1.)
|
||||
| _ -> (let rec p = function
|
||||
| 0 -> 1.
|
||||
| n -> (let res. = p x (n/2) in
|
||||
res *. res *. (if n mod 2 = 1 then x else 1.)
|
||||
in p x n)
|
||||
;;
|
||||
|
||||
(*Correction v3*)
|
||||
let power x n = match n with
|
||||
| 0 -> (match x with
|
||||
| 0. -> failwith "power 0^0 impossible"
|
||||
| _ -> 1.)
|
||||
| _ -> (match x with
|
||||
| 1. -> 1.
|
||||
| 0. -> 0.
|
||||
| -1. -> if n mod 2 = 0 then 1. else -1.)
|
||||
| _ -> (let rec p x = function
|
||||
| 0 -> 1.
|
||||
| n -> p (x*x) (n/2) *. (if n mod 2 = 1 then x else 1.)
|
||||
in p x n)
|
||||
;;
|
||||
```
|
||||
|
||||
Complexity :
|
||||
$$
|
||||
x^0 -> 1 \ | \
|
||||
x^1 -> (x^0)^2 -> 2 \ | \
|
||||
x^2 -> x^1 -> 3 \ | \
|
||||
x^4 -> x^2 -> 4 \ | \
|
||||
x^8 -> x^4 -> 5 \ | \
|
||||
x^16 -> x^8 -> 6 \ | \
|
||||
x^(2^k) -> x^(2^k-1) -> k+2 \approx{k} \ | \
|
||||
n = 2^k -> K*log(n) \ | \
|
||||
log(n) = log(2^k) = k
|
||||
$$
|
||||
$$
|
||||
= O(log(n))
|
||||
$$
|
||||
## Exercise 4.12 - Prime number
|
||||
```OCaml
|
||||
(* V1 *)
|
||||
let prime n =
|
||||
if n < 1 then
|
||||
invalid_args "n should not be inferior to zero"
|
||||
else if x = 2 then true
|
||||
else
|
||||
let rec pr n k =
|
||||
if n = k then
|
||||
true
|
||||
else if n mod k = 0 then
|
||||
false
|
||||
else
|
||||
check n (k + 1)
|
||||
in pr n 2;;
|
||||
(* V2 *)
|
||||
let prime n =
|
||||
if n < 1 then
|
||||
invalid_args "n should not be inferior to zero"
|
||||
else if x = 2 then true
|
||||
else
|
||||
let rec pr n k =
|
||||
if n = k then
|
||||
true
|
||||
else if n mod k = 0 then
|
||||
false
|
||||
else
|
||||
check n (k + 1)
|
||||
in (n = 2) || (n mod 2 = 1 and check n 3)
|
||||
(*correction*)
|
||||
let is_prime n =
|
||||
if n < 2 then
|
||||
invalid_arg "is_prime undefined for n < 2"
|
||||
else
|
||||
if n mod 2 = 0 tjen
|
||||
n = 2
|
||||
else
|
||||
let rec check d =
|
||||
if d*d > n then
|
||||
true
|
||||
else if n mod d = 0 then
|
||||
false
|
||||
else
|
||||
check (d + 2);
|
||||
check 3;;
|
||||
|
||||
```
|
||||
|
||||
## 4.13 - Perfect
|
||||
```Ocaml
|
||||
let is_perfect n =
|
||||
if n < 1 then
|
||||
invalid_arg "is_perfect: undefinded for n < 1"
|
||||
else
|
||||
let rec perfect d =
|
||||
if d = n then
|
||||
1
|
||||
else if n mod d > n then
|
||||
d + perfect (d + 1)
|
||||
else
|
||||
perfect (d + 1)
|
||||
in perfect d;;
|
||||
|
||||
(*v2*)
|
||||
let is_perfect n =
|
||||
if n < 1 then
|
||||
invalid_arg "is_perfect: undefinded for n < 1"
|
||||
else
|
||||
let rec perfect d =
|
||||
if d*d >= n then
|
||||
1 + (if d*d = n then d else 0)
|
||||
else if n mod d > n then
|
||||
d + n/d + sumd (d+1)
|
||||
else
|
||||
perfect (d + 1)
|
||||
in perfect d;;
|
||||
```
|
||||
## Hanoi
|
||||
```Ocaml
|
||||
(* displays moves: source -> destination *)
|
||||
|
||||
let move source destination =
|
||||
print_int source ;
|
||||
print_string " -> " ;
|
||||
print_int destination ;
|
||||
print_newline()
|
||||
;;
|
||||
|
||||
let hanoi n =
|
||||
let rec play n source auxiliary destination =
|
||||
if n = 1 then
|
||||
move source destination
|
||||
else
|
||||
begin
|
||||
play (n-1) source destination auxiliary;
|
||||
move source destination;
|
||||
play (n-1) auxiliary source destination
|
||||
end
|
||||
in
|
||||
if n < 0 then
|
||||
invalid_arg "Hanoi: number of disks invalid"
|
||||
else
|
||||
play n 1 2 3
|
||||
;;
|
||||
hanoi 3;;
|
||||
```
|
68
Algo/B1/Séminaire/Introduction.md
Normal file
@ -0,0 +1,68 @@
|
||||
|
||||
<center><img src="https://i.imgur.com/8xTIMVy.png " width=auto height=400 /> </center>
|
||||
|
||||
## An algorithm is
|
||||
- a set of rules (finite)
|
||||
- sequence (finite)
|
||||
- The goal is to take an input and give an output with the solution
|
||||
|
||||
## How to write an algorithm
|
||||
1) What do you have available ; What is the output that your searching for => this is call specifications
|
||||
2) How : find resolution methods and choose the best one
|
||||
3) Formalism : shape it like a computer talk
|
||||
4) Translate :
|
||||
|
||||
## Compilation and interpretation
|
||||
### Compiler
|
||||
```mermaid
|
||||
flowchart TD
|
||||
|
||||
A[High Level source code] -->|Compiler| B[Machine code]
|
||||
|
||||
B --> C[execution]
|
||||
|
||||
B --> D[execution 2]
|
||||
|
||||
B --> E[execution ...]
|
||||
```
|
||||
The compiler depends on
|
||||
- Language of the source code
|
||||
- The computer it will run the code
|
||||
|
||||
Advantages :
|
||||
- 1 translation
|
||||
- Optimises the code
|
||||
|
||||
> C or C++ language use the compiler
|
||||
### Interpretation
|
||||
The interpretor is a live compiler that translate in realtime.
|
||||
|
||||
Disavantages:
|
||||
- Don't optimize the code
|
||||
|
||||
Avantages:
|
||||
- We can share only the original source code
|
||||
|
||||
> Javascript use interpretation
|
||||
|
||||
## Language families
|
||||
There is two families in the language word, the imperative and the declarative
|
||||
### Imperative
|
||||
- State (of the memory)
|
||||
- Instruction that will modify the state of the memory
|
||||
- and again...
|
||||
- output
|
||||
|
||||
### Declarative
|
||||
- Defines relations between the input and the output
|
||||
|
||||
In the declarative languages we have
|
||||
- The functional languages
|
||||
- $f:x -> x+1$
|
||||
- The logical languages
|
||||
$$x\in{N}$$
|
||||
$$x>1$$
|
||||
$$x<3$$
|
||||
$$\text{-> } x=2$$
|
||||
|
||||
|
27
Algo/B1/Séminaire/Remediation.md
Normal file
@ -0,0 +1,27 @@
|
||||
```Ocaml
|
||||
let rec search n d =
|
||||
|
||||
if n = 0 then
|
||||
|
||||
false
|
||||
|
||||
else if n mod 10 = d then
|
||||
|
||||
true
|
||||
|
||||
else search (n/10) d
|
||||
|
||||
|
||||
|
||||
let rec chiffre_maximal n =
|
||||
if n < 10 && n > 0 then
|
||||
n
|
||||
else
|
||||
let dernier_chiffre = n mod 10 in
|
||||
let reste = n / 10 in
|
||||
let max_reste = chiffre_maximal reste in
|
||||
if dernier_chiffre > max_reste then
|
||||
dernier_chiffre
|
||||
else
|
||||
max_reste;;
|
||||
```
|
3
Algo/B1/Séminaire/Weird stuff.md
Normal file
@ -0,0 +1,3 @@
|
||||
```Ocaml
|
||||
10 mod (-3) = 10 mod 3
|
||||
```
|
BIN
Algo/B1/Séminaire/assets/basics-meme.png
Normal file
After Width: | Height: | Size: 466 KiB |
BIN
Algo/B1/Séminaire/assets/exception-meme.png
Normal file
After Width: | Height: | Size: 654 KiB |
BIN
Algo/B1/Séminaire/assets/fact function response.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
Algo/B1/Séminaire/assets/filter-meme.png
Normal file
After Width: | Height: | Size: 464 KiB |
BIN
Algo/B1/Séminaire/assets/functions-meme.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
Algo/B1/Séminaire/assets/if-meme.png
Normal file
After Width: | Height: | Size: 293 KiB |
BIN
Algo/B1/Séminaire/assets/recursivite-meme.png
Normal file
After Width: | Height: | Size: 867 KiB |
BIN
Algo/B1/Séminaire/assets/unitaire-meme.png
Normal file
After Width: | Height: | Size: 789 KiB |