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.