(* ######################################################################## *) (* # # *) (* # Les types composés # *) (* # # *) (* ######################################################################## *) (* Les intervalles *) (* --------------- *) (* en ocaml : type intervalle = float * float ;; *) type intervalle == float * float ;; let (creeintervalle : float -> float -> intervalle) = function x -> function y -> if (x < y)then (x, y) else failwith " x < y ";; let (BorneInf : intervalle -> float) = function (inf,sup) -> inf ;; let (BorneSup : intervalle -> float) = function (inf,sup) -> sup ;; let (est_intervalle : intervalle -> bool) = function i -> (BorneInf i) < (BorneSup i) ;; let (intervalles_disjoints : intervalle -> intervalle -> bool) = function a -> function b -> (est_intervalle a) & (est_intervalle b) & ( (BorneSup a < BorneInf b) or (BorneInf a > BorneSup b));; (* Cinq minutes plus tard *) (* ----------------------- *) (* On peut exprimer un instant dans une journée, à la minute près, par deux entiers, le premier compris entre 0 et 23 et le second compris entre 0 et 59. Par exemple « Cinq heures et trente minutes » est représenté par les entiers 5 et 30. Concevoir une fonction qui, à partir d'un instant t exprimé par deux entiers, rend les deux entiers qui représenteront l'heure qu'il sera 5 minutes après $t$. Par exemple (5,30) devra renvoyer (5,35), mais (3,56) devra renvoyer (4,1) et enfin (23,59) devra renvoyer (0,4).*) let CinqMinutesPlusTard h m = if(m<55) then (h,m+5) else if(h<23) then (h+1, m-55) else (0,m-55);; (* A la seconde près *) (* ----------------- *) (* A présent, nous voulons manipuler des heures à la seconde près, et étendre les opérations possibles. Pour cela, il sera souvent intéressant de convertir un instant, représenté par trois entiers (h:m:s) (représentant respectivement les heures, les minutes et les secondes) en le nombre de secondes depuis le début de la journée (un entier). *) (* Construire le type horaire *) type horaire == int * int * int ;; let (creehoraire : int -> int -> int -> horaire) = function h -> function m -> function s -> if ((h<0) or (h>23) or (m<0) or (m>59) or (s<0) or (s>59)) then failwith "0 int) = function (h,m,s) -> h ;; let (min : horaire -> int) = function (h,m,s) -> m ;; let (sec : horaire -> int) = function (h,m,s) -> s ;; (* Concevoir et écrire en Caml une fonction qui à partir d'un objet de type horaire et représentant un instant t, renvoie le nombre de secondes écoulés entre le début de la journée et l'instant t.*) let (horaire_sec : horaire -> int) = function h -> (3600 * heure h) + (60 * min h) + sec h ;; (* Concevoir et écrire en Caml une fonction qui fait l'opération inverse.*) let (sec_horaire : int -> horaire) = function s -> (s / 3600, (s mod 3600) / 60, s mod 60) ;; (* Concevoir et écrire en Caml une fonction qui à partir de deux instants t_1 et t_2 de type horaire indique si t_1 est antérieur ou non à t_2.*) let (chronologie : horaire -> horaire -> bool) = function h1 -> function h2 -> horaire_sec h1 < horaire_sec h2 ;; (* Concevoir et \'ecrire en \emph{Caml} une fonction qui à partir de deux instants $t_1$ et $t_2$ de type \texttt{horaire} renvoie un autre objet de type \texttt{horaire}, indiquant la durée qui sépare les deux instants.*) let (diff_horaire : horaire -> horaire -> horaire) = function h1 -> function h2 -> sec_horaire (horaire_sec h2 - horaire_sec h1) ;; (* Les vecteurs *) (* ------------ *) (* Construire un type vecteur.*) type vecteur == float * float * float ;; let (creevecteur : float -> float -> float -> vecteur) = function x -> function y -> function z -> (x,y,z);; let (Abscisse : vecteur -> float) = function (x,y,z) -> x;; let (Ordonnee : vecteur -> float) = function (x,y,z) -> y;; let (Cote : vecteur -> float) = function (x,y,z) -> z;; let Somme (x1,y1,z1) (x2,y2,z2) = (x1+.x2, y1+.y2, z1+.z2) ;; let Somme v1 v2 = (Abscisse v1 +. Abscisse v2, Ordonnee v1 +. Ordonnee v2, Cote v1 +. Cote v2);; let ProduitScalaire (x1,y1,z1) (x2,y2,z2) = x1*.x2 +. y1*.y2 +. z1*.z2;; (* ProduitScalaire:float * float * float -> float * float * float -> float = *) let ProduitScalaire v1 v2 = Abscisse v1 *. Abscisse v2 +. Ordonnee v1 *. Ordonnee v2 +. Cote v1 *. Cote v2;; (* ProduitScalaire : vecteur -> vecteur -> float = *) let Norme (x,y,z) = sqrt(ProduitScalaire (x,y,z) (x,y,z)) ;; let Norme v = sqrt(ProduitScalaire v v);; let Homothetie k (x,y,z) = (k*.x, k*.y, k*.z);; let Homothetie k v = (k*.Abscisse v, k*.Ordonnee v, k*.Cote v);; let Unitaire v = let coeff = 1. /. Norme v in Homothetie coeff v;; (* Les rationnels *) (* -------------- *) (* Construire un type rationnel.*) type fraction == int * int;; let (creefraction : int -> int -> fraction) = function n -> function d -> (n,d);; let (numerateur : fraction -> int) = function (n,d) -> n ;; let (denominateur : fraction -> int) = function (n,d) -> d ;; let (SommeFraction : fraction -> fraction -> fraction) = function a -> function b -> let n = (numerateur a * denominateur b) + (numerateur b * denominateur a) and d = (denominateur a * denominateur b) in (n,d);; let (ProduitFraction : fraction -> fraction -> fraction) = function a -> function b -> let n = numerateur a * numerateur b and d = denominateur a * denominateur b in (n,d);; let rec PGCD a b = if (a = b) or (b=0) then a else if (a=0) then b else if a < b then PGCD a (b-a) else PGCD (a-b) b;; let (ReduireFraction : fraction -> fraction) = function a -> let p = PGCD (numerateur a) (denominateur a) in ((numerateur a)/p, (denominateur a)/p);; (* Les complexes *) (* ------------- *) (* Construire un type complexe.*) type complexe == float * float ;; let (creecomplexe : float -> float -> complexe) = function r -> function i -> (r, i);; let (reelle : complexe -> float) = function (r, i) -> r ;; let (imaginaire : complexe -> float) = function (r, i) -> i ;; let (somme : complexe -> complexe -> complexe) = function a -> function b -> let r = reelle a +. reelle b and i = imaginaire a +. imaginaire b in creecomplexe r i ;; let (produit : complexe -> complexe -> complexe) = function a -> function b -> let r1 = reelle a and r2 = reelle b and i1 = imaginaire a and i2 = imaginaire b in creecomplexe (r1 *. r2 -. i1 *. i2) (r1 *. i2 +. i1 *. r2) ;; let (norme : complexe -> float) = function c -> let carre x = x *. x in sqrt ( carre (reelle c) +. carre (imaginaire c) );; let PI = 3.14;; let (argument : complexe -> float) = function c -> let r = reelle c and i = imaginaire c in if (r = 0.0 && i = 0.0) then 0.0 else if (r = 0.0) then if (i > 0.0) then PI/.2.0 else -.PI/.2.0 else let a = atan(i/.r) in if ( r <. 0.0) then a +. PI else a ;; let (paire : complexe -> float * float) = function c -> (norme c, argument c);; (* Les flottants *) (* ------------- *) (* Construire un type flottant.*) type flottant == int * int ;; let (creeflottant : int -> int -> flottant) = function m -> function c -> (m, c);; let (mantisse : flottant -> int) = function (a,b) -> a ;; let (exposant : flottant -> int) = function (a,b) -> b ;; let (prod : flottant -> flottant -> flottant) = function x -> function y -> let m = mantisse x * mantisse y and c = exposant x + exposant y in creeflottant m c;; let rec puissance x = function 0 -> 1 |n -> x * puissance x (n-1);; let (som : flottant -> flottant -> flottant) = function x -> function y -> if exposant y < exposant x then let m_x = mantisse x * puissance 10 (exposant x - exposant y) in creeflottant (m_x + mantisse y) (exposant y) else let m_y = mantisse y * puissance 10 (exposant y - exposant x) in creeflottant (m_y + mantisse x) (exposant x);; (* prod (35,-1) (2,-1);; - : flottant = 70, -2 som (35,-1) (8,-3);; - : flottant = 3508, -3 *)