12/04/2017 Exercice 1-1 Ecrire une fonction booléenne present qui aura deux arguments, une liste de mesures nommée l et une chaîne de caractères nommée nom représentant le nom d’un expérimentateur. Cette fonction indique si l’expérimentateur a effectué une mesure contenue dans la liste l. Programmation fonctionnelle [("luc",10);("lea",12);("agathe",14);("lea",8);("louis",22);("louis",13); ("lea",18)] # let rec present l nom = match l with [] -> false # let l nom = match | (no , va) :: trec -> present if no = nom then true l with [] -> | (no , va) :: t -> if no = nom then t nom ;; else present else present t nom ;; val present : ('a * 'b) list -> 'a -> bool = <fun> Cours 12 : Correction du CC2 Révisions Licence 1 Année 2016 – 2017 # present [("luc",10);("lea",12);("agathe",14);("lea",8);("louis",22);("louis",13); ("lea",18)] "lea" ;; - : bool = true # present [("luc",10);("lea",12);("agathe",14);("lea",8);("louis",22);("louis",13); ("lea",18)] "martin" ;; - : bool = false Par N. VINCENT Licence 1 - programmation fonctionnelle Exercice 1-3 Exercice 1-2 Ecrire une fonction fcompte qui aura deux arguments, une liste de mesures nommée l et une chaîne de caractères nommée nom représentant le nom d’un expérimentateur. Cette fonction calcule le nombre de mesures effectuées par l’expérimentateur dont le nom est le second argument. [("luc",10);("lea",12);("agathe",14);("lea",8);("louis",22);("louis",13); ("lea",18)] # fcompte2 li "luc" "lea" ;; - : int * int = (1, 3) # let fcompte2 l nom1 nom2 = let rec faux acc1 acc2 ll name1 name2 = match ll with [] -> acc1 , acc2 | (name1 , va) :: t -> faux (1 + acc1) acc2 t name1 name2 | (name2 , va) :: t -> faux acc1 (1 + acc2) t name1 name2 | h :: t -> faux acc1 acc2 t name1 name2 in faux 0 0 l nom1 nom2 ;; 3 Exercice 1-3 Ecrire une fonction fcompte2 qui à partir d’une liste de mesures fournie en argument et de deux autres arguments, des chaînes de caractère, calcule un couple contenant respectivement le nombre de mesures de chaque expérimentateur. [("luc",10);("lea",12);("agathe",14);("lea",8);("louis",22);("louis",13); ("lea",18)] # let fcompte2 l nom1 nom2 = let rec faux acc1 acc2 ll name1 name2 = match ll with [] -> acc1 , acc2 | (no , va) :: t -> if no = name1 then faux (1 + acc1) acc2 t name1 name2 else if no = name2 then faux acc1 (1 + acc2) t name1 name2 else faux acc1 acc2 t name1 name2 in faux 0 0 l nom1 nom2 ;; val fcompte2 : ('a * 'b) list -> 'a -> 'a -> int * int = <fun> # fcompte2 li "luc" "lea" ;; - : int * int = (1, 3) Licence 1 - programmation fonctionnelle Ecrire une fonction fcompte2 qui à partir d’une liste de mesures fournie en argument et de deux autres arguments, des chaînes de caractère, calcule un couple contenant respectivement le nombre de mesures de chaque expérimentateur. [("luc",10);("lea",12);("agathe",14);("lea",8);("louis",22);("louis",13); ("lea",18)] # let fcompte2 l nom1 nom2 = (fcompte l nom1 , fcompte l nom2) # let rec fcompte fcompte l nom l nom = let= rec match fauxl with acc ll[]name -> 0 = | (no , va) :: t -> if no match ll with [] -> acc= nom then 1 + fcompte t nom | (no , va) :: t -> if no = name else then fcompte faux (1t nom + acc) ;; t name val fcompte : ('a * 'b) list -> 'a -> int <fun> else= faux acc t name # in fcompte faux 0 l nom li "lea" ;; ;; -val : int fcompte = 3 : ('a * 'b) list -> 'a -> int = <fun> # fcompte li "lea" ;; - : int = 3 Licence 1 - programmation fonctionnelle 2 5 Warning 11: this match case is unused. # fcompte2 li "luc" "lea" ;; Warning 11: this match case is unused. - : int * int = (7, 0) val fcompte2 : ('a * 'b) list -> 'a -> 'a -> int * int = <fun> 4 Licence 1 - programmation fonctionnelle Exercice 1-4 Ecrire une fonction mesure qui aura pour arguments une liste de mesures nommée l et une chaîne de caractères nommée nom qui représente le nom d’un expérimentateur. Cette fonction doit créer la liste des mesures réalisées par l’expérimentateur nom . [("luc",10);("lea",12);("agathe",14);("lea",8);("louis",22);("louis",13); ("lea",18)] # let rec mesure l nom = match l with [] -> [] | (nom , va) :: t -> va :: mesure t nom | _:: t -> mesure t nom ;; # mesure li "lea" ;; - : int list = [10; 12; 14; 8; 22; 13; 18] # let rec mesure l nom = match l with [] -> [] | (no , va) :: t -> if no = nom then va :: mesure t nom else mesure t nom ;; # mesure li "lea" ;; - : int list = [12; 8; 18] # let mesure l nom = let rec faux acc ll name = match ll with [] -> acc | (no , va) :: t -> if no = nom then faux (acc@ [va]) t name else faux acc t name in faux [] l nom ;; Licence 1 - programmation fonctionnelle 6 1 12/04/2017 Exercice 1-6 Exercice 1-5 Ecrire une fonction fmoy qui à partir d’une liste de mesures l calcule la moyenne des mesures réalisées par un expérimentateur dont le nom est indiqué en argument nom. [("luc",10);("lea",12);("agathe",14);("lea",8);("louis",22);("louis",13); ("lea",18)] # let fmoy l nom = let rec som acc ll = match ll with [] -> acc | h:: t -> som (acc+h) t in float_of_int (som 0 (mesure l nom)) /. float_of_int (fcompte l nom) ;; # let fmoy l nom = let rec faux acc lll name name == match lll with with [] [] -> -> float_of_int float_of_int (acc) (acc) /./. float_of_int float_of_int (List.length (List.length (mesure l nom)) | (no , va) :: t -> if no = name then faux (acc +va) t name else faux acc t name in faux 0 l nom ;; Licence 1 - programmation fonctionnelle Ecrire une fonction fmax qui à partir d’une liste de mesures l et de deux arguments nom1 et nom2, calcule un couple d’entiers contenant respectivement les valeurs maximum mesurées par chacun des expérimentateurs. On vérifiera que la liste comporte au moins une mesure réalisée par chacun des expérimentateurs, sinon une exception indiquera ce cas. # let fmax l nom1 nom2 = match (present l nom1) && (present l nom2) with false -> failwith "un des expérimentateurs sans mesure" | _ -> let rec maxi acc ll = match ll with [] -> acc | h:: t -> maxi (max acc h) t in (maxi (List.hd(mesure l nom1)) (mesure l nom1) , maxi (List.hd(mesure l nom2)) (mesure l nom2)) ;; val fmax : ('a * 'b) list -> 'a -> 'a -> 'b * 'b = <fun> # fmax li "louis" "lea" ;; - : int * int = (22, 18) 7 Licence 1 - programmation fonctionnelle 8 Exercice 1-7 Exercice 2 Ecrire une fonction resum qui à partir d’une liste de mesures nommées l construit une liste dont les éléments sont des couples dont le premier élément est le nom d’un expérimentateur et le second est le nombre de mesures faites par cet expérimentateur et présentes dans la liste l. Ecrire une fonction f qui calcule la somme des éléments de rang impair dans une liste d’entiers, la liste est donnée dans l’argument appelé l. # let resum l = let rec faux acc ll = match ll with [] -> acc | (no,va):: t -> if present acc no then faux acc t else faux (acc @ [(no, (fcompte l no))]) t in faux [] l ;; # f [3 ; 7 ; -1 ; 8 ; 5 ; 7] ;; - : int = 7 # f [3 ; 7 ; -1 ; 8 ; 5 ] ;; - : int = 7 # resum li ;; - : (string * int) list = [("luc", 1); ("lea", 3); ("agathe", 1); ("louis", 2)] Licence 1 - programmation fonctionnelle # let rec f l = match l with [] -> 0 | [h] -> h | h1::h2:: t -> h1 + f t ;; val f : int list -> int = <fun> 9 Licence 1 - programmation fonctionnelle Exercice 3 Exercice 3 On considère la fonction suivante : let rec f l = match l with | [] -> [] | h::t -> if h mod 2 = 0 then (f t) @ [h] else h::(f t) ;; 1°/ Ecrire l’interprétation de cette fonction f. On considère la fonction suivante : let rec f l = match l with | [] -> [] | h::t -> if h mod 2 = 0 then (f t) @ [h] else h::(f t) ;; val f : int list -> int list = <fun> On pourra vérifier son résultat sur l’argument [1 ; 10 ; 4 ; 1 ; 5; 3]. Donner une version terminale de cette fonction f. let f1 liste = let rec faux ll acc = match ll with [] -> acc | h::t -> if h mod 2 = 0 then (faux t (h::acc)) else (faux t (acc@[h])) in faux liste [] ;; 2°/ Quel est le résultat de l’application de f sur l’argument : [1 ; 10 ; 4 ; 1 ; 5 ; 3] ? 1:: f [10 ; 4 ; 1 ; 5 ; 3] # f1 [1 ; 10 ; 4 ; 1 ; 5; 3] ;; - : int list = [4; 10; 1; 1; 5; 3] 1 :: (f [ 4 ; 1 ; 5 ; 3]) @ [10] 1:: (f [1 ; 5 ; 3]) @ [4] @ [10] 1::1:: (f [5 ; 3]) @ [4] @ [10] 10 [1 ; 1; 5 ; 3 ; 4 ; 10] 1::1::5:: (f [3]) @ [4] @ [10] 1::1::5::3 (f [ ]) @ [4] @ [10] Licence 1 - programmation fonctionnelle 11 let f2 liste = let rec faux ll acc1 acc2 = match ll with [] -> acc1 @ acc2 | h::t -> if h mod 2 = 0 then faux t acc1 (h::acc2) else faux t (acc1@[h]) acc2 in faux liste [] [] ;; # f2 [1 ; 10 ; 4 ; 1 ; 5; 3] ;; - : int list = [1; 1; 5; 3; 4; 10] Licence 1 - programmation fonctionnelle 12 2 12/04/2017 Exercice 3 Géométrie On considère la fonction suivante : let rec f l = match l with | [] -> [] | h::t -> if h mod 2 = 0 then (f t) @ [h] else h::(f t) ;; Les vecteurs peuvent être modélisés par un enregistrement Donner une version terminale de cette fonction f. let f1 liste = let rec faux ll acc1 acc2 = match ll with [] -> acc1 @ acc2 | h::t -> if h mod 2 = 0 then faux t acc1 (h::acc2) else faux t (acc1@[h]) acc2 in faux liste [] [] ;; # f1 [1 ; 10 ; 4 ; 1 ; 5; 3] ;; - : int list = [1; 1; 5; 3; 4; 10] # type vecteur = { x : float ; y : float } ;; type vecteur = { x : float; y : float; } Produit scalaire # let prod u v = (u.x)*.(v.x) +. (u.y)*.(v.y) ;; val prod : vecteur -> vecteur -> float = <fun> let f3 liste = let rec mir ll acc = match ll with [] -> acc | h::t -> mir t (h::acc) in let rec faux ll acc = match ll with [] -> acc | h::t -> if h mod 2 = 0 then (faux t (acc@[h])) else (faux t (h::acc)) in faux (mir liste []) [] ;; # f3 [1 ; 10 ; 4 ; 1 ; 5; 3] ;; - : int list = [1; 1; 5; 3; 4; 10] Licence 1 - programmation fonctionnelle # let u1 = {x = 1. ; y=2. } ;; val u1 : vecteur = {x = 1.; y = 2.} # let u2 = {x=(-2.) ; y = 1. } ;; val u2 : vecteur = {x = -2.; y = 1.} 13 Licence 1 - programmation fonctionnelle Géométrie # type vecteur = { x : float ; y : float } ;; type vecteur = { x : float; y : float; } Droite définie par un élément de type vecteur et une constante # type complexe = {re : float ; im : float} ;; type complexe = { re : float; im : float; } addition # let add c1 c2 = {re = (c1.re +. c2.re) ; im = (c1.im +. c2.im) } ;; val add : complexe -> complexe -> complexe = <fun> # let adroit p c m = ((prod p m)+.c)=0. ;; val adroit : vecteur -> float -> vecteur -> bool = <fun> # let droit1 m = adroit n c m ;; val plan1 : vecteur -> bool = <fun> 14 Nombres complexes Appartenance à une droite : ax+by+c=0 # let n = { x = 1. ; y = 2.} and c = 0. ;; val n : vecteur = {x = 1.; y = 2.} val c : float = 0. # prod u1 u2 ;; - : float = 0. produit # droit1 { x = 0. ; y = 0.} ;; - : bool = true # let prod c1 c2 = {re = ((c1.re)*.(c2.re))-.((c1.im)*.(c2.im)) ; im = ((c1.re)*.(c2.im))+.((c1.im)*.(c2.re)) } ;; val prod : complexe -> complexe -> complexe = <fun> # droit1 { x = -1. ; y = 0.} ;; - : bool = false Licence 1 - programmation fonctionnelle 15 Licence 1 - programmation fonctionnelle 16 Représentation d'un polynôme conversion a n xn + … + a 0 # type complexe = {re : float ; im : float} ;; type complexe = { re : float; im : float; } # type vecteur = { x : float ; y : float } ;; type vecteur = { x : float; y : float; } Complexe associé à un vecteur Ensemble de monômes a,n Liste de paires d'entiers affichage # let p1 = [(1 , 0) ; (3, 1) ; ((-2) , 5)] ;; val p1 : (int * int) list = [(1, 0); (3, 1); (-2, 5)] # let affmono (a , n) = if n = 0 then print_int a # let vect2comp u = {re = u.x ; im = u.y } ;; val vect2comp : vecteur -> complexe = <fun> else begin print_string "+" ; print_int a ; print_string "x^" ; print_int n end ;; val affmono : int * int -> unit = <fun> # affmono (3 , 5) ;; Licence 1 - programmation fonctionnelle 17 +3x^5- : unit = () Licence 1 - programmation fonctionnelle 18 3 12/04/2017 Calcul de la valeur en un point Affichage d'un polynôme an x + … + a0 Calcul des puissances n # let rec puis x n = if n = 0 then 1 else x*puis x (n-1) ;; # let affpoly p = List.map affmono p ;; val puis : int -> int -> int = <fun> val affpoly : (int * int) list -> unit list = <fun> Version terminale # let p1 = [(1 , 0) ; (3, 1) ; ((-2) , 5)] ;; val p1 : (int * int) list = [(1, 0); (3, 1); (-2, 5)] # affpoly p1 ;; 1+3x^1+-2x^5- : unit list = [(); (); ()] Licence 1 - programmation fonctionnelle 19 Calcul de la valeur en un point # let expo x n = let rec f acc x n = if n = 0 then acc else f (x*acc) x (n-1) in f 1 x n ;; val expo : int -> int -> int = <fun> # expo 8 2 ;; - : int = 64 Licence 1 - programmation fonctionnelle 20 Calcul de la valeur en un point an x + … + a0 n an x + … + a0 version terminale n # let rec valeur p m = let match c1 xp=with match x with | (x1,x2) -> x1 # let value p m = let c1 x = match x with | (x1,x2) -> x1 in let c2 x |=[]match -> 0 x with | (x1,x2) -> x2 in match p| with (v , e) ::t -> (v)* (expo m (e)) + valeur t m ;; in let c2 x = match x with | (x1,x2) -> x2 in let rec f acc p m = match p with val valeur |: [] (int ->*0int) list -> int -> int = <fun> # p1 ;; | h::t -> (c1 h)* (expo m (c2 h)) + valeur t m ;; | [] -> acc | h::t -> f (acc+(c1 h)* (expo m (c2 h))) t m val - : (int valeur * int) : (int list*=int) [(1,list0);->(3, int1); ->(-2, int = 5)]<fun> # p1 valeur ;; p1 1 ;; in f 0 p m ;; val valeur : (int * int) list -> int -> int = <fun> - : :(int int *=int) 2 list = [(1, 0); (3, 1); (-2, 5)] # p1 ;; # valeur p1 1 ;; - : (int * int) list = [(1, 0); (3, 1); (-2, 5)] - : int = 2 Licence 1 - programmation fonctionnelle 21 Addition de deux polynômes # value p1 1 ;; - : int = 2 Licence 1 - programmation fonctionnelle 22 Addition de deux polynômes Version terminale Première version # let rec add p1 p2 = match (p1,p2) with | (a,[]) -> a | ([],a) -> a | ((a1,n1)::t1 , (a2,n2)::t2) -> if n1 < n2 then (a1,n1)::add t1 p2 else if n1=n2 then (a1+a2,n1)::add t1 t2 else (a2,n2)::add p1 t2 ;; val add : (int * 'a) list -> (int * 'a) list -> (int * 'a) list = <fun> # p1 ;; - : (int * int) list = [(1, 0); (3, 1); (-2, 5)] let p2 = [(1, 0); (2, 1); (3, 6)] ;; val p2 : (int * int) list = [(1, 0); (2, 1); (3, 6)] # addition p1 p2 ;; - : (int * int) list = [(2, 0); (5, 1); (-2, 5); (3, 6)] Licence 1 - programmation fonctionnelle 23 # let addition p1 p2 = let rec addi acc p1 p2 = match (p1,p2) with | (a,[]) -> acc@a | ([],a) -> acc@a | ((a1,n1)::t1 , (a2,n2)::t2) -> if n1 < n2 then addi (acc@[(a1,n1)]) t1 p2 else if n1=n2 then addi (acc@[(a1+a2,n1)]) t1 t2 else addi (acc@[(a2,n2)]) p1 t2 in addi [] p1 p2 ;; val addition : (int * 'a) list -> (int * 'a) list -> (int * 'a) list = <fun> # addition p1 p2 ;; - : (int * int) list = [(2, 0); (5, 1); (-2, 5); (3, 6)] Licence 1 - programmation fonctionnelle 24 4