diff --git a/README.md b/README.md index 044ef1d2077e779c002515735783fb2694475e7b..a7a7bf3e3d4360e36fd029c6bdc5295109cbb0f4 100644 --- a/README.md +++ b/README.md @@ -8,28 +8,28 @@ (2024) indique qu'il s'agit des supports de l'an dernier qui sont à mettre à jour -| jour | heure | type | sujet | supports / remarques | -| ----- | ------------- | ---------- | --------------------------- | ------------------------------------------------------------------------------- | -| 20/01 | 8h | CM1 | Intro & Lambda-Calcul | [Diapositives Intro](cm/lifpf-cm0.pdf), [Diapositives Cours](cm/lifpf-cm1.pdf) | -| | 9h45 | TD1 sauf B | Lambda-Calcul | [Sujet](td/lifpf-td1-enonce.pdf), [corrigé](td/lifpf-td1-correction.pdf) | -| | 11h30 | TD1 Grp B | | | -| 27/01 | 8h | CM2 | OCaml | (2024) [Diapositives](cm/lifpf-cm2.pdf), [Script démos](cm/cm2-demo.md) | -| | 9h45 ou 11h30 | TP1 | Prise en main | (2024) [Sujet](tp/tp1.md), [corrigé](tp/tp1.ml) | -| 03/02 | 8h | TD2 | Lambda-Calcul | (2024) [Sujet](td/lifpf-td2-enonce.pdf), [corrigé](td/lifpf-td2-correction.pdf) | -| | 9h45 ou 11h30 | TP2 | Listes | (2024) [Sujet](tp/tp2.md), [corrigé](tp/tp2.ml) | -| 10/02 | 8h | CM3 | Struct. ind. + types param. | (2024) [Diapositives](cm/lifpf-cm3.pdf) | -| | 9h45 ou 11h30 | TP3 | Arbres | (2024) [Sujet](tp/tp3.md), [corrigé](tp/tp3.ml) | -| 17/02 | 8h | TD3 | Arbres | (2024) [Sujet](td/lifpf-td3-enonce.pdf), [corrigé](td/lifpf-td3-correction.pdf) | -| | 9h45 ou 11h30 | TP4 | Arbres génériques | (2024) [Sujet](tp/tp4.md), [corrigé](tp/tp4.ml) | -| 10/03 | 8h | CM4 | Ordre sup. | (2024) [Diapositives](cm/lifpf-cm4.pdf) | -| | 9h45 | TD4 | Ordre sup. | (2024) [Sujet](td/lifpf-td4-enonce.pdf), [corrigé](td/lifpf-td4-correction.pdf) | -| 17/03 | 8h | CM5 | Modules | (2024) [Diapositives](cm/lifpf-cm5.pdf) | -| | 9h45 ou 11h30 | TP5 | Struct. gen. | (2024) [Sujet](tp/tp5.md), [corrigé de l'exercice 1](tp/tp5.ml) | -| 24/03 | 8h | TD5 | Ordre sup. | (2024) [Sujet](td/lifpf-td5-enonce.pdf), [corrigé](td/lifpf-td5-correction.pdf) | -| | 9h45 ou 11h30 | TP6 | Transf. struct. | (2024) [Sujet](tp/tp6.md), corrigés dans les TD/TPs référencés dans le sujet | -| 31/03 | 9h45 ou 11h15 | TP7 | App. OCaml (à changer ?) | (2024) [Sujet](tp/tp7.md), [corrigé](tp/tp7.zip) | -| 07/04 | 8h | CM6 | Foncteurs | (2024) [Diapositives](cm/lifpf-cm6.pdf), [code](cm/cm6-code.ml) | -| | 9h45 | TD6 | Foncteurs | (2024) [Sujet](td/lifpf-td6-enonce.pdf), [corrigé](td/lifpf-td6-correction.pdf) | +| jour | heure | type | sujet | supports / remarques | +| ----- | ------------- | ---------- | --------------------------- | ------------------------------------------------------------------------------ | +| 20/01 | 8h | CM1 | Intro & Lambda-Calcul | [Diapositives Intro](cm/lifpf-cm0.pdf), [Diapositives Cours](cm/lifpf-cm1.pdf) | +| | 9h45 | TD1 sauf B | Lambda-Calcul | [Sujet](td/lifpf-td1-enonce.pdf), [corrigé](td/lifpf-td1-correction.pdf) | +| | 11h30 | TD1 Grp B | | | +| 27/01 | 8h | CM2 | OCaml | [Diapositives](cm/lifpf-cm2.pdf), [Script démos](cm/cm2-demo.md) | +| | 9h45 ou 11h30 | TP1 | Prise en main | [Sujet](tp/tp1.md), [corrigé](tp/tp1.ml) | +| 03/02 | 8h | TD2 | Lambda-Calcul | [Sujet](td/lifpf-td2-enonce.pdf) | +| | 9h45 ou 11h30 | TP2 | Listes | [Sujet](tp/tp2.md) | +| 10/02 | 8h | CM3 | Struct. ind. + types param. | (2024) [Diapositives](cm/lifpf-cm3.pdf) | +| | 9h45 ou 11h30 | TP3 | Arbres | (2024) [Sujet](tp/tp3.md) | +| 17/02 | 8h | TD3 | Arbres | (2024) [Sujet](td/lifpf-td3-enonce.pdf) | +| | 9h45 ou 11h30 | TP4 | Arbres génériques | (2024) [Sujet](tp/tp4.md) | +| 10/03 | 8h | CM4 | Ordre sup. | (2024) [Diapositives](cm/lifpf-cm4.pdf) | +| | 9h45 | TD4 | Ordre sup. | (2024) [Sujet](td/lifpf-td4-enonce.pdf) | +| 17/03 | 8h | CM5 | Modules | (2024) [Diapositives](cm/lifpf-cm5.pdf) | +| | 9h45 ou 11h30 | TP5 | Struct. gen. | (2024) [Sujet](tp/tp5.md) | +| 24/03 | 8h | TD5 | Ordre sup. | (2024) [Sujet](td/lifpf-td5-enonce.pdf) | +| | 9h45 ou 11h30 | TP6 | Transf. struct. | (2024) [Sujet](tp/tp6.md) | +| 31/03 | 9h45 ou 11h15 | TP7 | App. OCaml (à changer ?) | (2024) [Sujet](tp/tp7.md) | +| 07/04 | 8h | CM6 | Foncteurs | (2024) [Diapositives](cm/lifpf-cm6.pdf), [code](cm/cm6-code.ml) | +| | 9h45 | TD6 | Foncteurs | (2024) [Sujet](td/lifpf-td6-enonce.pdf) | ### Annales diff --git a/cm/lifpf-cm1.pdf b/cm/lifpf-cm1.pdf index 01d537d6d15dd65e1aefee65ec8837c6190f1c2a..819437db49d14c9451403e1027f9f32c93e29411 100644 Binary files a/cm/lifpf-cm1.pdf and b/cm/lifpf-cm1.pdf differ diff --git a/cm/lifpf-cm2.pdf b/cm/lifpf-cm2.pdf index 7766701dcb981084579a5150243928257a3c02c4..19341ed53f0087d72e29aad708a26b6b4a2e14ed 100644 Binary files a/cm/lifpf-cm2.pdf and b/cm/lifpf-cm2.pdf differ diff --git a/td/lifpf-td2-enonce.pdf b/td/lifpf-td2-enonce.pdf index 1f77e970eb31bee3f0370b67d9d83b99685cb2e3..f3d3f5a042485c734b293624ce1e47ca3c603cc7 100644 Binary files a/td/lifpf-td2-enonce.pdf and b/td/lifpf-td2-enonce.pdf differ diff --git a/tp/tp1.ml b/tp/tp1.ml new file mode 100644 index 0000000000000000000000000000000000000000..c46c53f129bb6d403fec27f56df06d1c8ab138c3 --- /dev/null +++ b/tp/tp1.ml @@ -0,0 +1,250 @@ +(**********************************************************************) +(* 1.1.1 *) +(3 * 2) + (5 / 2);; +3.2 +. (7.4 /. 2.0);; +"AC" ^ "/" ^ "DC";; +true || (false && false);; + +(* && est prioritaire sur || *) +(false && false) || true;; + +(* 3 < 2.0 provoque une erreur car 3 et 2.0 n'ont pas le même type *) + +(**********************************************************************) +(* 1.1.2 *) + +(* float_of_int 3.0 provoque une erreur car 3.0 n'est pas un int *) +float_of_int 3;; +int_of_float;; +int_of_float 3.5 + 2;; +float_of_int (int_of_float 3.6 + 2) +. 1.5;; +(not false) && false;; +2 < 3 && "b" < "ab";; + +(**********************************************************************) +(* 1.1.3 *) +let x1 = 3.5 +. float_of_int 2 in +x1 +. 3.0 +;; + +let x1 = 3.5 +. float_of_int 2 in +let x2 = x1 *. x1 in +x2 *. 2.0 +;; + +(**********************************************************************) +(* 1.1.4 *) + +(if true then 3 else 5) > 4 + +(**********************************************************************) +(* 1.2 *) +let f x = x + 1;; + +3 + f 3 + +let discriminant a b c = (b *. b) -. (4.0 *. a *. c) + +(* Le type affiche par l'interpréteur est float -> float -> float -> float *) + +(** [discriminant a b c] calcule le discriminant d'un trinôme. Cette fonction + est utile pour trouver les racines d'un trinôme. + @param a le coefficient d'ordre 2 + @param b le coefficient d'ordre 1 + @param c le coefficient d'ordre 0 + @return le discriminant *) +let discriminant (a : float) (b : float) (c : float) : float = + (b *. b) -. (4.0 *. a *. c) +;; + +discriminant;; +discriminant 2.0 8.0 8.0 + +(* Erreur de type sur l'utilisation de a dans la def suivante: *) +(* + let discriminant (a:int) (b:float) (c:float): float = + b *. b -. 4.0 *. a *. c;; +*) + +(**********************************************************************) + +(* 1.3.1 *) +type couleur = Rouge | Jaune | Bleu;; + +(* La valeur Rouge est bien définie et reconnue comme étant de type couleur *) +Rouge;; + +(* L'égalité est bien (pré)définie sur les couleurs *) +Rouge = Rouge;; +Rouge != Bleu;; + +(* De même il existe un ordre par défaut sur les couleurs *) +Bleu > Jaune + +type couleur = Rouge | Jaune | Bleu | Violet | Orange | Vert + +type couleur = + | Rouge + | Jaune + | Bleu + | Violet + | Orange + | Vert + | RJB of int * int * int +;; + +(* le type est "int * float" c'est-à -dire une paire d'int et de float *) +3, 5.6;; + +(* c'est le triplet de type int * int * int *) +3, 5, 6 + +(**********************************************************************) +(* 1.3.2 *) + +let nom_couleur c = + match c with + | Rouge -> "rouge" + | Jaune -> "jaune" + | Bleu -> "bleu" + | Vert -> "vert" + | Violet -> "violet" + | Orange -> "orange" + | _ -> "mélange" + +(* + let nom_couleur c = + match c with + | Rouge -> "rouge" + | Jaune -> "jaune" + | Bleu -> "bleu" + | Vert -> "vert" + | Violet -> "violet" + | Orange -> "orange";; + Erreur: this pattern-matching is not exhaustive. + Elle indique que le match ne couvre pas tous les cas possibles. +*) + +(* + let nom_couleur c = + match c with + | _ -> "mélange" + | Rouge -> "rouge" + | Jaune -> "jaune" + | Bleu -> "bleu" + | Vert -> "vert" + | Violet -> "violet" + | Orange -> "orange";; + Erreur: this pattern-matching is not exhaustive. + Elle indique que le match ne couvre pas tous les cas possibles. +*) + +(** Génère le paragraphe pour [n] bouteilles de bières. + @param n + le nombre de bouteilles de bièere sur le mur au début du paragraphe. + @return le paragraphe *) +let paragraphe_bottles (n : int) : string = + match n with + | 0 -> + "No more bottles of beer on the wall, no more bottles of beer.\n" + ^ "Go to the store and buy some more, 99 bottles of beer on the wall." + | 1 -> + "1 bottle of beer on the wall, 1 bottle of beer.\n" + ^ "Take one down and pass it around, no more bottles of beer on the wall." + | 2 -> + "2 bottles of beer on the wall, 2 bottles of beer.\n" + ^ "Take one down and pass it around, 1 bottle of beer on the wall." + | k -> + string_of_int k ^ " bottles of beer on the wall, " ^ string_of_int k + ^ " bottles of beer.\n" ^ "Take one down and pass it around, " + ^ string_of_int (k - 1) + ^ " bottles of beer on the wall." +;; + +(* tests *) + +paragraphe_bottles 0;; +paragraphe_bottles 1;; +paragraphe_bottles 2;; +paragraphe_bottles 7 + +(**********************************************************************) +(* 2.1 *) + +(** Renvoie la somme des n premiers entiers + @param n le nombre d'entiers à sommer + @return la somme *) +let rec sum_n (n : int) : int = if n <= 0 then 0 else n + sum_n (n - 1) + +(** [factorielle n] calcule la factorielle des [n] premiers entiers + @param n doit être supérieur ou égal à 1 + @return !n *) +let rec factorielle n = if n <= 1 then 1 else n * factorielle (n - 1) + +(**********************************************************************) +(* 2.2 *) +(* Erreur car on essaie d'ajouter une string dans une int list + "2" :: 3 :: [];; +*) + +(** Cette fonction calcule la longueur d'une liste de `string`. + @param l la liste dont on veut la longueur + @return la longueur de l *) +let rec longueur (l : string list) : int = + match l with [] -> 0 | _ :: l2 -> 1 + longueur l2 + +(* La valeur de l'élément de list n'est pas utilisée dans le deuxième cas du match. + On a donc pas besoin de la recupérer dans une variable et on met _ pour plus de clarté. *) + +(** Cette fonction calcule la somme des éléments de la liste + @param l la liste dont on veut additionner les éléments + @return la somme des éléments de la liste *) +let rec sum_f (l : float list) : float = + match l with [] -> 0.0 | x :: l2 -> x +. sum_f l2 + +(** Cette fonction concatène les éléments de la liste en les séparant par [sep]. + @param l la liste dont on veut concaténer les éléments + @param sep le séparateur + @return + les éléments de la liste [l] concaténé et séparés les uns des autres par + [sep] *) +let rec join_s (l : string list) (sep : string) : string = + match l with + | [] -> "" + | s :: [] -> s + | s :: l2 -> + (* Plus général que le cas précédent car l2 n'est pas forcément vide. + Comme le match applique le premier cas dans l'ordre du programme, + Les listes à 1 élément ne passent pas dans le 3eme cas du match. *) + s ^ sep ^ join_s l2 sep +;; + +(* test *) +join_s [ "a"; "b"; "c" ] "|" + +(** Cette fonction créée une liste des int de n à 0 inclus. + @param n l'int de début de liste + @return la liste des entiers décroissants *) +let rec liste_n_0 (n : int) : int list = + if n <= 0 then [ 0 ] else n :: liste_n_0 (n - 1) +;; + +(* test *) +liste_n_0 12 + +(** [bottles_of_list [n1; n2; ...]] crée la liste des paragraphes de la chanson + 99 bottles of beer pour n1 puis n2 ... bouteilles. + @param l la liste des nombres de bouteilles à transformer + @return la liste des paragraphes correspondant aux int de l *) +let rec bottles_of_list (l : int list) : string list = + match l with + | [] -> [] + | n :: l2 -> paragraphe_bottles n :: bottles_of_list l2 + +let chanson_99_bottles = + let nums = liste_n_0 99 in + let paragraphes = bottles_of_list nums in + join_s paragraphes "\n\n" +;; + +print_endline chanson_99_bottles diff --git a/tp/tp2.md b/tp/tp2.md index c028c07464d5efa48eec8d00d9f1cf42d7f7dc5b..9853653f04ea898c41d2124ec89d124bc117491b 100644 --- a/tp/tp2.md +++ b/tp/tp2.md @@ -1,8 +1,6 @@ # LIFPF: TP2 récursion sur les listes -Finir le [TP1](tp1.md) avant de commencer ce TP. - -Le reste du TP consiste à travailler la récursion sur les listes. +Ce TP consiste à travailler la récursion sur les listes. Comme dans le TP précédent, on prendra soin: - de **donner le type** des arguments et le type de retour de chaque fonction; @@ -39,9 +37,11 @@ applatit [ [ 1; 2 ]; [ 3; 4; 5 ]; []; [ 6 ] ] = [ 1; 2; 3; 4; 5; 6 ];; applatit [ [ 1 ] ] = [ 1 ];; ``` -Faire une deuxième version `applatit2` ayant la même spécification que `applatit` mais qui n'utilise **pas** `concatene`. +Faire une deuxième version `applatit2` ayant la même spécification que `applatit` mais qui n'utilise **pas** `concatene` (et qui n'utilise aucune autre fonction, en particulier pas l'opérateur de concaténation prédéfini en OCaml). Tester cette fonction avec les mêmes tests que `applatit`. +> Fin de la partie 1, prévenez votre chargé de TP. + ## 2. Retournement de liste On souhaite implémenter une fonction `renverse` qui renverse une liste. @@ -70,6 +70,8 @@ On peut aussi remarquer que `renverse` peut se coder très facilement à partir Coder `renverse` en définissant `renverse_ajoute`. Définir tout d'abord `renverse_ajoute` avant `renverse` et tester. Essayer ensuite d'intégrer la définition de `renverse_ajoute` à l'intérieur de celle de renverse via un `let rec renverse_ajoute ... in ...`. +> Fin de la partie 2, prévenez votre chargé de TP + ## 3. Tri par insertion On code [l'algorithme de tri par insertion](https://fr.wikipedia.org/wiki/Tri_par_insertion) qui consiste, pour chaque élément, à l'insérer à la bonne place dans le reste de la liste préalablement triée. @@ -96,6 +98,8 @@ tri_insertion [ 1; 4; 2; 3 ] = [ 1; 2; 3; 4 ];; tri_insertion [ 1; 2; 3; 4 ] = [ 1; 2; 3; 4 ];; ``` +> Fin de la 3eme partie, prévenez votre chargé de TP + ## 4. Recherche dans une liste d'association On rappelle qu'une liste d'association est _une liste de paires `(clé, valeur)`_. @@ -114,6 +118,8 @@ Coder la fonction `cherche` qui va chercher une clé dans une liste d'associatio Bien penser à écrire des tests pour cette fonction. +> Fin de la 4eme partie, prévenez votre chargé de TP. + ## 5. Calculatrice en notation polonaise On souhaite implémenter une calculatrice en notation polonaise, c'est-à -dire calculant le résultat d'expressions dans lesquelles les **opérateurs sont placés avant leurs arguments**. @@ -180,3 +186,5 @@ eval_expr [ Op Mult; Cst 3; Cst 2 ] = [ Ok 6 ];; eval_expr [ Op Plus; Cst 3; Cst 5; Op Moins; Cst 2; Cst 7 ] = [ Ok 8; Ok (-5) ];; eval_expr [ Op Plus; Op Div; Cst 7; Cst 3 ] = [ ErrExpr ];; ``` + +> Fin de la 5eme partie, prévenez votre chargé de TP.