NFP119 : corrigé feuille d exercices 2

Documents pareils
Recherche dans un tableau

length : A N add : Z Z Z (n 1, n 2 ) n 1 + n 2

# let rec concat l1 l2 = match l1 with [] -> l2 x::l 1 -> x::(concat l 1 l2);; val concat : a list -> a list -> a list = <fun>

modules & compilation

Classes et Objets en Ocaml.

Machines virtuelles fonctionnelles (suite) Compilation ML Java

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

TD3: tableaux avancées, première classe et chaînes

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Cours Informatique Master STEP

Cours de Programmation 2

STAGE IREM 0- Premiers pas en Python

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;


Cours 1 : La compilation

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Logiciel Libre Cours 3 Fondements: Génie Logiciel

Présentation du langage et premières fonctions

Java Licence Professionnelle CISII,

OCL - Object Constraint Language

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Vérification de programmes et de preuves Première partie. décrire des algorithmes

Solutions du chapitre 4

Chapitre VI- La validation de la composition.

Initiation à l algorithmique

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Cours No 3 : Identificateurs, Fonctions, Premières Structures de contrôle.

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

Algorithmique & programmation

Les chaînes de caractères

Algorithmique et Programmation, IMA

TP3 : Manipulation et implantation de systèmes de fichiers 1

INF111. Initiation à la programmation impérative en C amini/cours/l1/inf111/ Massih-Reza Amini

Premiers Pas en Programmation Objet : les Classes et les Objets

Découverte de Python

Analyse de sécurité de logiciels système par typage statique

GOL502 Industries de services

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Conventions d écriture et outils de mise au point

Programme Compte bancaire (code)

Exercices types Algorithmique et simulation numérique Oral Mathématiques et algorithmique Banque PT

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

TP 1. Prise en main du langage Python

Principes des langages de programmation INF 321. Eric Goubault

Structurer ses données : les tableaux. Introduction à la programmation

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

Chapitre 10. Les interfaces Comparable et Comparator 1

Correction Code nécessaire à la compilation : let bs ="\\" let nl = "\n" ;; let appliquer = List.map ;; (* affichage d'un noeud *)

TP, première séquence d exercices.

Grandes lignes ASTRÉE. Logiciels critiques. Outils de certification classiques. Inspection manuelle. Definition. Test

MapReduce. Malo Jaffré, Pablo Rauzy. 16 avril 2010 ENS. Malo Jaffré, Pablo Rauzy (ENS) MapReduce 16 avril / 15

Module Administration BD Chapitre 1 : Surcouche procédurale dans les SGBDS

Initiation à la programmation en Python

Examen Médian - 1 heure 30

Introduction au langage C

Corrigé des TD 1 à 5

Plan du cours. Historique du langage Nouveautés de Java 7

Sub CalculAnnuite() Const TITRE As String = "Calcul d'annuité de remboursement d'un emprunt"

Java 1.5 : principales nouveautés

PROJET ALGORITHMIQUE ET PROGRAMMATION II

Algorithmique et Programmation Fonctionnelle

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Utilisation d objets : String et ArrayList

Logiciel Libre Cours 2 Fondements: Programmation

Arguments d un programme

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Bases de programmation. Cours 5. Structurer les données

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Notions fondamentales du langage C# Version 1.0

Qualité du logiciel: Méthodes de test

Les processus 2/54. Qu est-ce qu un processus? 3(6)/54. Se souvenir 1(1)/54. Le système de fichiers (exemple du disque dur)

Algorithmes récursifs

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Le prototype de la fonction main()

Informatique Générale

Cours de Programmation Impérative: Zones de mémoires et pointeurs

Conversion d un entier. Méthode par soustraction

TP : Gestion d une image au format PGM

PHP et mysql. Code: php_mysql. Olivier Clavel - Daniel K. Schneider - Patrick Jermann - Vivian Synteta Version: 0.9 (modifié le 13/3/01 par VS)

Organigramme / Algorigramme Dossier élève 1 SI

M2-Images. Rendu Temps Réel - OpenGL 4 et compute shaders. J.C. Iehl. December 18, 2013

DOCM Solutions officielles = n 2 10.

KL5121. Pour activer des sorties en fonction de la position d'un codeur

Utilitaires méconnus de StrataFrame

Programmation en Caml pour Débutants

Cours Fonctions de deux variables

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

SNT4U16 - Initiation à la programmation TD - Dynamique de POP III - Fichiers sources

introduction Chapitre 5 Récursivité Exemples mathématiques Fonction factorielle ø est un arbre (vide) Images récursives

Calcul matriciel. Définition 1 Une matrice de format (m,n) est un tableau rectangulaire de mn éléments, rangés en m lignes et n colonnes.

Plan du cours : Zippers. Des fonctions sur les listes avec position. Des fonctions sur les listes avec position

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Peut-on tout programmer?

Algorithmique et programmation : les bases (VBA) Corrigé

Programmation. fonctionnelle, impérative, logique et orientée objet

Programmation C++ (débutant)/instructions for, while et do...while

Glossaire des nombres

Transcription:

NFP119 : corrigé feuille d exercices 2 María-Virginia Aponte 10 octobre 2013 Exercice 1 1. Testez cette fonction en Ocaml pour les appels suivants : sommen(0), sommen(-1), sommen(1), sommen(3). L appel SommeN(n) calcule la somme des n premiers nombres positis 1 + 2 + 3 +... + n si n est positif, et 0 n est négatif ou nul. # sommen (0);; - : int = 0 # sommen (-1);; - : int = 0 # sommen 1;; - : int = 1 # sommen 3;; - : int = 6 2. Déroulez manuellement ces appels. Rappel : un déroulement récursif peut se faire manuellement en remplaçant chaque appel à la fonction par son corps où le paramètre formel est remplacé par le paramètre de l appel, puis en réalisant les opérations correspondantes (en mimant l exécution). Exemples pour la factorielle dans les transparents du cours. 3. sommen ( 1)= = i f 1<=0 then 0 e l s e... = 0 sommen( 0 ) = = i f 0<=0 then 0 e l s e... = 0 sommen( 3 ) = = i f 3<=0 then 0 e l s e 3 + sommen( 2 ) = 3 + sommen ( 2 ) = 3 + ( i f 2<=0 then 0 e l s e 2 + sommen (2 1)) = 3 + (2 + sommen ( 1 ) ) = 3 + (2 + ( i f 1<=0 then 0 e l s e 1 + sommen (1 1)) = 3 + 2 + (1 + sommen ( 0 ) ) = 3 + 2 + 1 + sommen( 0 ) = 3 + 2 + 1 + ( i f 0<=0 then 0 e l s e 0 + sommen ( 1)) = 3 + 2 + 1 + 0 = 6 1

4. Cette fonction termine-t-elle dans tous les cas? Pouvez vous dire pourquoi? Oui. Si n 0 elle termine car il n y a plus d appel récursif. Si n > 0 elle termine car chaque appel récursif se fait sur le paramètre n 1 qui est plus petit que n. Le cas de base où n = 0 est atteint en un n ombre fini d étapes. Exercice 2 Terminaison Considérez les définitions de fonctions suivantes. Ces fonctions terminent-elles toujours? Donnez un déroulement récursif manuel pour les appels donnés plus bas, puis testez ces appels dans la boucle intéractive d Ocaml. 1. # let rec fact n = if n=1 then 1 else n*fact(n-1);; Testez cette fonction avec les appels (fact 2), (fact 0) et fact (-1). Quel est le problème? Donnez une correction simple. Solution : Cette fonction termine pour les arguments positifis, mais ne termine pas si n est négatif ou nul. fact(0)= = if 0=1 then 1 else 0 * fact(0-1) = 0 * fact(-1) = 0 * (if -1=1 then 1 else (-1)* fact(-2)) = 0 * (-1)* fact(-2) = 0 * (-1) * fact(-2) = 0 * (-1) * (-2) * fact(-3) *... Une correction simple, consiste à changer la condition du cas de base de manière à capturer également ces deux cas-là. Cela donne : # let rec fact n = if n<=1 then 1 else n*fact(n-1);; 2. # let rec fact n = if n<=1 then 1 else n*fact(n+1);; Testez cette fonction avec les appels (fact 0) et (fact 1). Quel est le problème? Donnez une correction simple. Solution : Cette fonction ne termine que si l argument passé est plus petit ou égal à 1 ; S il est plus grand, la fonction boucle dans les appels récursifs : on fait un appel récursif pour un argument à chaque fois plus grand. Comme le cas de base est 1 ou plus petit, on ne s arrête jamais. fact 2 if 2<=1 then 1 else 2*fact (2+1) 2 * (fact(3)) 2 * (if 3<=1 then 1 else 3*factorielle (3+1)) 2 * (3*factorielle (4)) 3 * (2* (if 4<=1 then 1 else...)... 2

3. # let rec f n = f(n-1);; Testez cette fonction avec l appel f 0. Quel est le problème? Solution : Cette fonction ne termine jamais car elle n a qu un cas d appel récursif et pas de cas de base. 4. # let rec g n = if n<=0 then g(n-1) else g(n+1);; Testez cette fonction avec les appels g 0 et g 1. Quel est le problème? Solution : Cette fonction ne termine jamais car elle n a que des cas d appels récursifs et pas de cas de base. g 0 = = if 0<=0 then g(0-1) else g(0+1) = g(-1) = if -1<=0 then g(-1-1) else g(-1+1) = g(-2) = g(-3) =... g 1 = = if 1<=0 then g(1-1) else g(1+1) = g(2) = g(3) =... Exercice 3 1. Donnez une définition récursive dans un style mathématique pour cette fonction. 1 si b = 0 x b = x x (b 1) si b > 0 2. Ecrivez cette fonction en Ocaml. # let rec puissance x b = if b<=0 then 1 else x * puissance x (b-1);; val puissance : int -> int -> int = <fun> Notez que l on élargit le cas de base aux entiers plus petits ou égaux à 0. Pourquoi? 3. Testez votre fonction. Termine-t-elle toujours? Pourquoi? # puissance 3 0;; - : int = 1 # puissance 3 (-1);; - : int = 1 # puissance 3 2;; - : int = 9 Oui, elle termine (par un arugment similaire à celui donné pour l exercice 2). 3

Exercice 4 Question 1 Récursivité, programmation, fonctions d ordre supérieur Considérez les fonction suivantes : let lettre c = ( a <= c && c<= z ) or ( A <=c && c<= Z );; let rec moti (s,i) = if i<=0 then true else (lettre (s.[i])) && moti (s,(i-1));; val moti : string * int -> bool = <fun> # moti ("abcd456",3);; # moti ("abcd456",5);; 1. Donnez un déroulement récursif de l appel moti ("abcd456",3). Testez en Ocaml les exemples proposés plus haut. moti ("abcd456",2) = = if 2<=0 then true else (lettre (s.[2])) && moti (s,(1)) = lettre (s.[2])) && moti(s,(1)) = lettre ( c ) && moti(s,(1)) = true && moti(s,(1)) = moti(s,(1)) = (if 1<=0 then true else (lettre (s.[1])) && moti (s,(0))) = lettre (s.[1])) && moti (s,(0)) = lettre ( b )) && moti (s,(0)) = true && moti (s,(0)) = moti (s,(0)) = (if 0<=0 then true else...) = true moti ("abcd456",5) = = if 5<=0 then true else (lettre (s.[5])) && moti (s,(4)) = lettre (s.[5])) && moti(s,(4)) = lettre ( 5 ) && moti(s,(4)) = false && moti(s,(4)) = false 2. Donnez une définition mathématique de cette fonction. Que fait la fonction moti? Quel est le rôle du paramètre i? true si i 0 moti(s, i) = lettre(s.[i]) moti(s, i 1) si i > 0 L appel moti(s, i) teste si la sous-chaîne de s comprise entre les indices i... 0 est composée uniquement de lettres. Le parcours débute au caractère d indice i et termine au caractère d indice 0. Le rôle du paramètre i est de donner l indice de départ du parcours récursif. 3. On souhaite écrire une fonction qui teste si une chaîne est composée uniquement de lettres. Proposez une solution qui incorporent les fonctions lettre et moti. Cette dernière possède 2 arguments mais un seul change pendant les appels récursifs. Utilisez le schéma récursif 2 décrit dans les transparents du cours. 4

let est_mot s = let lettre c = ( a <= c && c<= z ) or ( A <=c && c<= Z ) in let rec moti i = if i<=0 then true else (lettre (s.[i])) && moti (i-1) in moti (String.length s -1) val est_mot : string -> bool = <fun> # est_mot "abc";; # est_mot "6B7s";; 4. Que fait la fonction suivante? Comparez la avec la fonction que vous avez écrite. Comment éffectue-telle le parcours récursif de la chaîne? Donnez un déroulement récursif pour étayer votre réponse. let est_mot s = let lettre c = ( a <= c && c<= z ) or ( A <=c && c<= Z ) in let rec parcours i = if i>= String.length s then true else (lettre (s.[i])) && parcours (i+1) in parcours 0;; val est_mot : string -> bool = <fun> # est_mot "abc";; # est_mot "687678";; Solution : La fonction est mot teste si une chaîne de caractères est uniquement composée de lettres. Elle utilise la fonction locale récursive parcours, qui parcourt la chaîne du premier au dernier indice en testant si le caractère visité est une lettre. Contrairement à la fonction moti, le parcours débute ici au premier caractère, et c est pourquoi le cas d arrêt teste si i>=string.length s, et le cas récursif fait un appel sur l indice suivant (i + 1). 5. La directive trace permet de tracer tous les appels déclenchés par une fonction récursive. Cela ne marche pas pour les fonctions récursives locales. Nous allons donc définir parcours globalement afin de tester plusieurs appels. Attention : il faut déclarer la fonction à tracer par # trace nom-fonction, où l on écrit explicitement un caractère # # let lettre c = ( a <= c && c<= z ) or ( A <=c && c<= Z ) ;; val lettre : char -> bool = <fun> # let rec parcours i = if i>= String.length s then true else (lettre (s.[i])) && parcours (i+1);; val parcours : int -> bool = <fun> # #trace parcours;; parcours is now traced. # parcours 0;; parcours <-- 0 parcours <-- 1 5

parcours <-- 2 parcours <-- 3 parcours --> true parcours --> true parcours --> true parcours --> true 6. Inspirez vous de l écriture compacte de la fonction palindrome dans les transparents du cours afin de donner une version plus courte de la fonction parcours qui utilise des opérateurs logiques plutôt qu une conditionnelle. # l e t est mot s= l e t l e t t r e c = ( a <= c && c<= z ) or ( A <=c && c<= Z ) i n l e t r e c parcours i = i>= ( S t r i n g. l e n g t h s ) l e t t r e ( s. [ i ] ) && parcours ( i +1) i n parcours 0 ; ; v a l est mot : s t r i n g > bool = <fun> Question 2 Inspirez-vous de la question précédente pour écrire la fonction qui transforme une chaîne de caractères composée uniquement de chiffres en un nombre entier. Indication : vous pourrez convertir chaque caractère vers son correspondant en chiffre entier, puis multiplier celui-ci par la puissance de 10 correspondant à son indice dans la chaîne. La somme de toutes ces opérations correspondra alos au résultat final. Exemple : le résultat à envoyer pour 283 est obetnue par 2 10 2 + 8 10 1 + 3 10 0 = 200 + 80 + 3 = 283. let chaine_vers_nombre s = let chiffre c = if ( 0 <= c && c<= 9 ) then Char.code c - Char.code 0 else failwith "chaine_vers_nombre" in let rec parcourt i pdix = if i<0 then 0 else (chiffre(s.[i]))* pdix + parcourt (i-1) (pdix*10) in parcourt (String.length s-1) 1;; val chaine_vers_nombre : string -> int = <fun> # chaine_vers_nombre "0";; - : int = 0 # chaine_vers_nombre "187";; - : int = 187 Question 3 1. Ecrivez une fonction testechaine qui prend une chaîne s et une fonction de test p et teste si tous les caractères de s satisfont le test p. Quel est le type de votre fonction? # l e t t e s t e C h a i n e s p= l e t r e c t e s t e R e c i = i>= ( S t r i n g. l e n g t h s ) p ( s. [ i ] ) && t e s t e R e c ( i +1) i n t e s t e R e c 0 ; ; v a l t e s t e C h a i n e : s t r i n g > ( char > bool ) > bool = <fun> 2. Réecrivez la fonction est mot par un simple appel à la fonction testechaine. 6

# l e t l e t t r e c = ( a <= c && c<= z ) or ( A <=c && c<= Z ) ; ; v a l l e t t r e : char > bool = <fun> # t e s t e C h a i n e bonjour l e t t r e ; ; : bool = t r u e # t e s t e C h a i n e bon67 l e t t r e ; ; : bool = f a l s e # l e t est mot s = t e s t e C h a i n e s l e t t r e ; ; v a l est mot : s t r i n g > bool = <fun> # est mot bon67 ; ; : bool = f a l s e # est mot bonjour ; ; : bool = t r u e 3. Ecrivez une fonction est nombre qui teste si une chaîne ne contient que des nombres par un appel à testechaine. # l e t nombre c = 0 <= c && c<= 9 ; ; v a l nombre : char > bool = <fun> # l e t est nombre s = t e s t e C h a i n e s nombre ; ; v a l est nombre : s t r i n g > bool = <fun> # est nombre 8 7 5 0 ; ; : bool = t r u e Exercice 5 Polymorphisme, typage. Pour les fonctions suivantes, tentez de découvrir leur type, puis comparez votre réponse avec celle donnée par Ocaml. # let f(x,y) = (y,x);; val f : a * b -> b * a = <fun> # let f(x,y) = x^y;; val f : string * string -> string = <fun> # let f(x,y) = (x+y, x-y, x*y);; val f : int * int -> int * int * int = <fun> Ici, x et y ne peuvent pas être à la fois de type int et string. # let f(x,y) = (x+y, x^y);; This expression has type int but is here used with type string Ici, appliquer f équivaut à appliquer fst. La fonction f devient une soret d alias pour fst. Elles ont donc des types identiques. # let f x = fst x;; val f : ( a * b) -> a = <fun> 7

Ici, x est de type quelconque. Par ailleurs, fst est appliquée sur y, et donc celui-ci doit nécesairement avoir le type d une paire. # let f(x,y) = (x, fst y);; val f : a * ( b * c) -> a * b = <fun> Même raisonnement qu avant mais cette fois sur x et y. # let f(x,y) = (fst x, fst y);; val f : ( a * b) * ( c * d) -> a * c = <fun> Même raisonnement sur x et y. De plus, les premières composantes de x et y sont nécessairement de type int, ainsi que le résultat de la fonction. # let f(x,y) = fst x + fst y;; val f : (int * a) * (int * b) -> int = <fun> # let g x y = (x,y);; val g : a -> b -> a * b = <fun> # let g x y = (x,y,x&&y);; val g : bool -> bool -> bool * bool * bool = <fun> Exercice 6 Filtrage. Lorsqu il y a erreur, expliquez les messages affcihés par Ocaml, et proposez une solution. Pour les fonctions sans erreur, testez-les sur plusieurs exemplez et expliquez ce qu elles font. Solution : La fonction voyelle teste si un caractère est une voyelle. # voyelle b ;; # voyelle i ;; La fonction oparith est définie de sorte que le premier cas filtre tous les argument possibles de la fonction. Du coup, elle est polymorphe et accepte n importe quel type d argument. De plus, elle répond false toujours. La solution est d inverser les deux filtres : #let oparith c = match c with _ -> false;; + - * / -> true val oparith : a -> bool = <fun> # oparith 1;; # oparith + ;; (* Correction *) #let oparith c = match c with + - * / -> true 8

_ -> false;; val oparith : a -> bool = <fun> # oparith 1;; This expression has type int but is here used with type char # oparith + ;; # oparith 1;; # oparith + ;; La fonction sommetriple compare son entrée avec deux cas de filtres de structure différente, et donc, dont les types sont différents. L erreur signalé est une erreur de typage. La solution est de changer le deuxième filtre pour que ce soit un triplet. # let sommetriple a = match a with (x,y,z) -> x+y+z (0,0,0) -> -1;; Warning: this match case is unused. val sommetriple : int * int * int -> int = <fun> # sommetriple (0,0,0);; - : int = 0 La fonction sommetriple est maintenant bien typée, mais elle ne fait pas ce que l on veut : le dernier cas n est jamais utilisé, car le premier filtre capture toutes les entrées. On inverse leur ordre : #let sommetriple a = match a with (0,0,0) -> -1 (x,y,z) -> x+y+z;; val sommetriplebis : int * int * int -> int = <fun> #sommetriple (0,0,0);; - : int = -1 La fonction sommetriplebis est mal typée car elle renvoie des valeurs de types différents dans ces deux cas. La fonction reponse ne repertorie pas tous les cas possibles de son argument. L erreur signalé par Ocaml nous dit que le filtrage est non exhaustif. Du coup, la fonction n est pas définie pour tous les cas : elle échoue pour les cas non capturés par les filtres donnés. # let reponse r = match r with"oui" -> trueue "Oui" -> true "OUI" -> true;; Warning: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: "" val reponse : string -> bool = <fun> val reponse : string -> bool = <fun> # reponse "oui";; 9

# reponse "non";; Exception: Match_failure ("", 2, 0). La solution est de compléter le filtrage : # let reponse r = match r with"oui" -> true "Oui" -> true "OUI" -> true _ -> false;; val reponse : string -> bool = <fun> # reponse "oui";; # reponse "non";; Exercice 7 Définir un type enregistrement date pour modéliser une date composée d un numéro de jour, d un numéro de mois et d une année. type date = {jour:int; mois:int; annee: int};; type date = { jour : int; mois : int; annee : int; } Ecrivez ensuite : 1. Un exemple de date dans la variable aujourd hui. 2. Une fonction bissextile qui teste si une année est bissextile. # let bissextile a = (a mod 4 =0) && (not (a mod 100 = 0) or (a mod 400 = 0));; val bissextile : int -> bool = <fun> # bissextile 2000;; # bissextile 1900;; # bissextile 2004;; 3. Une fonction joursmois qui calcule le nombre de jours dans un mois pour une année donnée. # let joursmois m a = match m with 4 6 9 11 -> 30 2 -> if bissextile a then 29 else 28 _ -> 31 val joursmois : int -> int -> int = <fun> # joursmois 2 2004;; - : int = 29 10

# joursmois 2 2005;; - : int = 28 # joursmois 3 2006;; - : int = 31 4. En utilisant les deux fonctions précédentes, écrire une fonction lendemain qui étant donné une date supposée correcte calcule la date du lendemain. # let lendemain d = if d.jour < joursmois d.mois d.annee then {jour= d.jour+1; mois=d.mois; annee = d.annee} else if d.mois < 12 then {jour= 1; mois=d.mois+1; annee = d.annee} else {jour= 1; mois= 1; annee = d.annee+1} val lendemain : date -> date = <fun> #let aujourd hui = {jour=27; mois=2; annee = 2006};; val aujourd hui : date = {jour = 27; mois = 2; annee = 2006} # lendemain aujourd hui;; - : date = {jour = 28; mois = 2; annee = 2006} Exercice 8 Définissez un type employe caractérisé par un nom, un salaire, et une date d entrée dans l entreprise. 1. Ecrivez une fonction qui en prenant deux employés, renvoyer celui dont le salaire est le plus élévé. 2. Ecrivez une fonction pour calculer l ancienneté d un employé en mois et années (par exemple 2 mois, ou 1 an et 2 mois). #type employe = {nom: string; salaire: float; datearrivee: date};; #type duree = {n_mois: int; n_annees: int};; #let anciennete aujourd hui {datearrivee = e} = let soustrait_dates d1 d2 = if d1.annee = d2.annee then {n_mois = d1.mois - d2.mois; n_annees = 0} else if d1.mois = d2.mois then {n_mois = 0; n_annees = d1.annee-d2.annee} else if d1.mois > d2.mois then {n_mois = d1.mois - d2.mois; n_annees = d1.annee-d2.annee} else {n_mois = (12-d2.mois)+ d1.mois; n_annees = d1.annee-d2.annee-1} in soustrait_dates aujourd hui e;; val anciennete : date -> employe -> duree = <fun> # let sep2000 = {jour =5; mois=9; annee = 2000};; val sep2000 : date = {jour = 5; mois = 9; annee = 2000} # let martin = {nom = "Martin"; salaire = 2200.50; datearrivee=sep2000};; val martin : employe = {nom = "Martin"; salaire = 2200.5; datearrivee = {jour = 5; mois = 9; annee = 2000}} # anciennete aujourd hui martin;; 11

- : duree = {n_mois = 5; n_annees = 5} # let plus_paye e1 e2 = if e1.salaire > e2.salaire then e1 else e2;; 12