vault backup: 2023-11-13 13:50:53

This commit is contained in:
2023-11-13 13:50:53 +01:00
parent 480ec6cbfe
commit bb839a2db9
25 changed files with 61 additions and 31 deletions

View 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

View 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
View 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).

View 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

View 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>

View 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

View 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)|

View 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
```

View 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>
```

View 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 = ()

View 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
```
![Alt](https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/fact%20function%20response.png)
> ⚠️ 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
```

View 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;;
```

View 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$$

View 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;;
```

View File

@ -0,0 +1,3 @@
```Ocaml
10 mod (-3) = 10 mod 3
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 KiB