## 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 = # (*teatcher version*) # let mirror n = 10 *(n mod 10)+n/10;; val mirror : int -> int = ``` ```Ocaml # let abba(n) = n*100 + mirror(n) ;; val abba: int -> int = ``` ```Ocaml # let stammer(n) = abba(mirror(n)) * 10 000 + abba(n) ;; val stammer: int -> int = ``` ## 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 = (*logical or*) # let or_if a b = if a then true else b;; val or_if: bool -> bool -> bool = (*logical implication*) # let imply_if a b = if a then b else true;; val imply_if: bool -> bool -> bool = (*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 = # let min2 number1 number2 = if number1 > number2 then number2 else number1 val min2 : 'a -> 'a -> 'a = # 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 = # 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 = # let middle3 x y z = x + y + z - min3 x y z - max x y z ;; val middle3 = int -> int -> int = #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 = # 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 = ``` ## 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 = # 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 = # 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 = # 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 = (*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 = ``` ## 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 = let strange = function | (0, n) -> 0 | (m, 0) -> 2*m | (m, n) -> m*n ;; val strange: int*int -> int = let or3 = function | (true, _, _) -> true | (_, true, _) -> true | (_, _, true) -> true | _ -> false val or3: bool*bool*bool -> bool = let or3-simple = function | (false, false, false) -> false | _ -> true val or3-simple: bool*bool*bool -> bool = ``` ### 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 = ``` ```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 = # 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) ```