# CorrectionExamen2019
## Exo 1 : typage
### Question 1
```ocaml=
f1 : int -> int ref -> int
f2 : 'a -> 'a ref -> 'a ref -> unit
f3 : (* int ref versus ref *)
f4 : ('a ref -> bool) -> 'a ref -> unit
```
## Exo 2 : Tak
### Question 2
```ocaml=
let rec tak x y z =
if y<z then
tak (tak (x-1) y z) (tak (y-1) z x) (tak(z-1) x y)
else
z
```
### Question 3
```ocaml=
let table = Hashtbl.create 17
let rec tak x y z =
if y<z then
memo_tak (memo_tak (x-1) y z)
(memo_tak (y-1) z x)
(memo_tak (z-1) x y)
else
z
and memo_tak x y z =
try Hashtbl.find table (x,y,z)
with Not_found -> let v = tak x y z in
Hashtbl.add table (x,y,z) v ; v
```
## Exo 3 : Evaluation
### Question 4
Initialement :
```ocaml=
t = [| 0; 1; 2 |]
r = { a = [| t; t |]; b = t }
```
Après `r.b.(0) <- 10` :
```ocaml=
t = [| 10; 1; 2 |]
r = { a = [| t; t |]; b = t }
```
Après `r.a.(0).(0) <- 4` :
```ocaml=
t = [| 4; 1; 2 |]
r = { a = [| t; t |]; b = t }
```
Après `r.a.(0) <- [|0;0|]` :
```ocaml=
s = [| 0 ; 0 |]
t = [| 4; 1; 2 |]
r = { a = [| s; t |]; b = t }
```
### Question 5
La fonction `mystere` décrémente `x` récursivement jusqu'à arriver `1`puis ajoute, à ce `1`, les anciens `x` qui ont été retenus sous `y`.
```ocaml=
(* On commence par retenir y=5 qu'on ajoutera à la toute fin, avant ça on
appelle mystere en décrémentant x. *)
mystere 2 => x:= 2 + !x
mystere 3 => x:= 3 + !x
mystere 4 => x:= 4 + !x
mystere 5 => x:= 5 + !x
```
On a `1+2+3+4+5=15` donc `mystere x; !x` où `x` est une référence vers `5` donne `15`.
### Question 6
```ocaml=
let f l = List.map (fun x -> incr x; if !x>2 then (ref 10) else x) l
(* La fonction incr incrémente de 1 une référence entière *)
```
On peut représenter les itérations de `List.map` par les listes successives suivantes :
Début : `[r ; r; r; r]` où `r -> 1` (`r` pointe vers `1`)
Itération 1 : `[r ; r; r; r]` où `r -> 2`
Itération 2 : `[r ; r'; r; r]` où `r -> 3` et `r' -> 10`
Itération 3 : `[r ; r'; r''; r]` où `r -> 4`, `r' -> 10` et `r'' -> 10`
Itération 4 : `[r ; r'; r''; r''']` où `r -> 5`, `r' -> 10`, `r'' -> 10` et `r''' -> 10`
Le résultat est donc une liste contenant 4 références toutes distinctes pointant vers les valeurs `5`, `10`, `10` et `10` respectivement.
## Exo 4 : Radix
### Question 7
```ocaml=
1=>1=>N(false,V,N(true,V,V))
4=>100=>N(false,N(false,N(false,N(true,V,V),V),V),V)
5=>101=>N(false,V,N(false,N(false,N(false,V,N(true,V,V),V),V),V),V)
6=>110=>N(false,N(false,V,N(false,V,N(true,V,V))),V)
(* mais il faut les combiner: *)
let a1 = N(false ,
N(false,
N(false,
V,
N(true,V,V)
),
N(false,
V,
N(true,V,V)
)
),
N(true,
N(false,
V,
N(true,V,V)
),
V
))
```
En examen, produire le dessin aurait suffit car la question est trop calculatoire.
### Question 8
```ocaml=
let rec find x t = match t with
| V -> false
| N (b,t0,t1) ->
if x=0 then b
else let r = x mod 2 in
let x2 = x/2 in
if r = 0 then find x2 t0
else find x2 t1
```
### Question 9
```ocaml=
let rec add t x = match t with
| V -> add (N (false, V, V)) x
| N (b, t0, t1) ->
if x = 0 then N (true, t0, t1)
else let r = x mod 2 in
let x2 = x/2 in
if r = 0 then N (b, add t0 x2, t1)
else N (b, t0, add t1 x2)
```
### Question 10
```ocaml=
let from_list l =
List.fold_left add V l
```
### Question 11
La liste l est la représentation en binaire de l'entier en base 10 que l'on veut calculer dans cette question.
```ocaml=
let list_to_int l =
List.fold_left (fun acc b -> 2 * acc + b) 0 l
```
### Question 12
```ocaml=
let to_list t =
let paths = ref [] in
let rec tlp p t =
match t with
| V -> ()
| N (b, t0, t1) ->
if b then paths := p :: !paths;
tlp (0::p) t0;
tlp (1::p) t1 in
tlp [] t;
List.map list_to_int !paths
```
### Question 13
```ocaml=
let rec union t1 t2 = match t1, t2 with
| V, t | t, V -> t
| N (b1, t11, t12), N (b2, t21, t22) ->
N (b1||b2, union t11 t21, union t12 t22)
```
Ou, plus concis mais moins efficace :
```ocaml=
let union t1 t2 =
List.fold_left add t1 (to_list t2)
```