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