(* =============== Esercizi del cap. 1.15 =================== *) (* ------------- 7 ------------- *) (* val max : 'a * 'a * 'a -> 'a *) let max3(n1,n2,n3) = if n1>n2 && n1>n3 then n1 else if n2>n1 && n2>n3 then n2 else n3;; (* oppure: max2 : 'a * 'a -> 'a *) let max2 (x,y) = if x>y then x else y;; let max3 (n1,n2,n3) = max2(n1,max2(n2,n3));; (* ------------- 8 ------------- *) (* val data : int * string -> bool *) let data (d,m) = d>0 & match m with "novembre" | "aprile" |"giugno" | "settembre" -> d<=30 | "febbraio" -> d<=28 | "gennaio"|"marzo"|"maggio"|"luglio"|"agosto"|"ottobre" -> d<=31 | _ -> false (* ------------- 9 ------------- *) (* sumof : int -> int *) (* versione ricorsiva *) let rec sumof = function 0 -> 0 | n -> n + sumof (n-1) (* versione ricorsiva di coda *) let sumof n = let rec aux(n,acc) = match n with 0 -> acc | _ -> aux(n-1,acc+n) in aux(n,0);; (* ------------- 10 ------------- *) (* sumbetween : int * int -> int *) (* versione ricorsiva *) let rec sumbetween(n,m) = if n>m then 0 else n + sumbetween(n+1,m) (* versione ricorsiva di coda *) let sumbetween (n,m) = let rec aux(n,acc) = if n>m then acc else aux(n+1,acc+n) in aux(n,0) (* ------------- 11 ------------- *) (* even : int -> bool determina se un numero e' pari *) let even n = n mod 2 = 0 (* powoftwo: int -> bool *) let rec powoftwo n = n = 1 or (even n && powoftwo (n / 2));; (* ------------- 12 ------------- *) (* ndiv : int -> int *) let ndiv n = (* aux(0,k) riporta il numero di divisori di n maggiori o uguali a k *) let rec aux(res,k) = if k>(n/2) then 1 (* n e' un divisore di se stesso *) else if n mod k = 0 then aux(res+1,k+1) else aux(res,k+1) in aux(0,1) (* ------------- 14 ------------- *) (* power : int * int -> int *) let power (b,e) = let rec aux(e,acc) = if e=0 then acc else aux(e-1,acc*b) in aux(e,1);; (* stringcopy : string * int -> string *) let stringcopy(s,n) = let rec aux(n,acc) = if n=0 then acc else aux(n-1,s^acc) in aux(n,"");; (* ------------- 15 ------------- *) (* isperfect : int -> bool *) let is_perfect n = (* riporta la somma dei divisori di n minori o uguali a d *) let rec sumdivisors d = if d=0 then 0 else if (n mod d = 0) then d + sumdivisors(d-1) else sumdivisors(d-1) in sumdivisors(n/2)=n ;; (* ------------- 19 ------------- *) (* minval: (int -> 'a) * int * int -> 'a*) (* versione ricorsiva *) let rec minval(f,n,m) = if n=m then f n else min (f n) (minval(f,n+1,m)) (* versione ricorsiva di coda *) let minval(f,n,m) = let rec aux(result,k) = if k>m then result else aux(min (f k) result,k+1) in aux(f n,n+1)