554 lines
11 KiB
Markdown
554 lines
11 KiB
Markdown
|
||
## 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;;
|
||
```
|