Programmation fonctionnelle

publicité
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
Téléchargement