TP La Flamme : tris et diviser pour régner

This commit is contained in:
2026-09-23 08:10:38 +02:00
parent 0d44ac2fc2
commit 78d9912fe2
@@ -0,0 +1,185 @@
## La Flamme - Algorithmes de tri
<img src="https://upload.wikimedia.org/wikipedia/commons/7/72/La_Flamme_-_Logo.png" alt="La Flamme" style="zoom:50%;" />
*La Flamme est une série Canal+ parodiant les émissions de téléréalité sentimentale de type Bachelor.*
---
### Contexte
Marc, le Bachelor de *La Flamme*, arrive à la **Grande Cérémonie des Roses Finale**.
Il a rencontré douze prétendant·e·s au fil des épisodes, et son équipe de production a calculé un **score de compatibilité** pour chacun·e.
Le problème : la liste est dans le désordre, et Marc doit la parcourir **classée du moins compatible au plus compatible** pour ménager le suspense et remettre la rose en dernier au ou à la grand·e vainqueur·e.
La production lui propose deux stratégies. À toi de les implémenter et de les comparer.
---
### Les données
Le score de compatibilité est calculé selon la formule :
```
score = charme + sincérité - drama + karaoké + cuisine
```
Marc aime le charme, la sincérité, le talent au karaoké et la cuisine maison.
En revanche, **chaque point de drama retire un point au score**.
```python
pretendants = [
{"nom": "Nadjim", "charme": 9, "sincerite": 5, "drama": 8, "karaoké": 7, "cuisine": 6, "score": 19},
{"nom": "Bibou", "charme": 6, "sincerite": 9, "drama": 2, "karaoké": 5, "cuisine": 8, "score": 26},
{"nom": "Sébastien", "charme": 8, "sincerite": 7, "drama": 3, "karaoké": 9, "cuisine": 4, "score": 25},
{"nom": "Valérie", "charme": 7, "sincerite": 8, "drama": 1, "karaoké": 6, "cuisine": 9, "score": 29},
{"nom": "Kevin", "charme": 5, "sincerite": 6, "drama": 9, "karaoké": 4, "cuisine": 3, "score": 9},
{"nom": "Stéphanie", "charme": 9, "sincerite": 4, "drama": 7, "karaoké": 8, "cuisine": 5, "score": 19},
{"nom": "Martial", "charme": 4, "sincerite":10, "drama": 1, "karaoké": 3, "cuisine": 7, "score": 23},
{"nom": "Chrystel", "charme": 8, "sincerite": 3, "drama": 6, "karaoké": 9, "cuisine": 6, "score": 20},
{"nom": "Didier", "charme": 6, "sincerite": 7, "drama": 4, "karaoké": 5, "cuisine":10, "score": 24},
{"nom": "Sandrine", "charme":10, "sincerite": 6, "drama": 5, "karaoké": 7, "cuisine": 4, "score": 22},
{"nom": "Jérémy", "charme": 3, "sincerite": 9, "drama": 2, "karaoké": 6, "cuisine": 8, "score": 24},
{"nom": "Natacha", "charme": 7, "sincerite": 5, "drama": 8, "karaoké":10, "cuisine": 5, "score": 19},
]
```
1. Vérifier sur deux ou trois prétendant·e·s que la formule donne bien le score indiqué.
---
### Partie 1 - Tri par sélection *(rappel de Première)*
La première stratégie de la production s'appelle **"La Rose du Moins Aimé"** :
> "À chaque cérémonie, on parcourt *tous* les prétendant·e·s encore classé·e·s, on identifie celui ou celle qui a le score le plus bas, et on le ou la place en premier. On recommence jusqu'à avoir tout classé."
1. En une phrase, expliquer en quoi cette description correspond au **tri par sélection**.
2. Compléter la fonction suivante :
```python
def tri_selection(tab):
n = len(tab)
for i in range(n):
idx_min = i
for j in range(i + 1, n):
if tab[j]["score"] < tab[idx_min]["score"]:
# à compléter
pass
# à compléter : echanger tab[i] et tab[idx_min]
return tab
```
3. Appliquer `tri_selection` à la liste `pretendants` et afficher les noms dans l'ordre obtenu.
4. Pour une liste de **n** prétendant·e·s, combien de comparaisons de scores effectue cet algorithme au total ? Exprimer le résultat en fonction de n, puis calculer pour n = 12.
---
### Partie 2 - Tri fusion *(diviser pour régner)*
La deuxième stratégie de la production s'appelle **"Les Deux Villas"** :
> "On sépare les prétendant·e·s en deux groupes. On classe chaque groupe séparément. Puis on réunit les deux listes classées en une seule, en les fusionnant."
C'est exactement l'algorithme de **tri fusion**, vu dans le cours.
#### 2.1 - La fonction `fusionner`
```python
def fusionner(gauche, droite):
resultat = []
i, j = 0, 0
while i < len(gauche) and j < len(droite):
if gauche[i]["score"] <= droite[j]["score"]:
resultat.append(gauche[i])
i += 1
else:
resultat.append(droite[j])
j += 1
return resultat + gauche[i:] + droite[j:]
```
1. Expliquer le rôle des variables `i` et `j` dans cette fonction.
2. Que se passe-t-il à la ligne `return resultat + gauche[i:] + droite[j:]` ?
Pourquoi est-il nécessaire d'ajouter `gauche[i:]` et `droite[j:]` à la fin ?
3. Appliquer *à la main* `fusionner` sur ces deux sous-listes déjà triées, et écrire le résultat étape par étape :
```python
gauche = [{"nom": "Kevin", "score": 9}, {"nom": "Martial", "score": 23}]
droite = [{"nom": "Chrystel", "score": 20}, {"nom": "Valérie", "score": 29}]
```
#### 2.2 - La fonction `tri_fusion`
```python
def tri_fusion(tab):
if len(tab) <= 1:
return tab
milieu = len(tab) // 2
gauche = tri_fusion( ) # à compléter
droite = tri_fusion( ) # à compléter
return fusionner(gauche, droite)
```
4. Compléter la fonction `tri_fusion`.
5. Quel est le **cas de base** de cette fonction récursive ? Pourquoi une liste de taille 0 ou 1 est-elle "déjà triée" ?
6. Appliquer `tri_fusion` à la liste `pretendants`. Vérifier que le résultat est identique à celui du tri par sélection.
#### 2.3 - Déroulé de l'algorithme
7. Sur la sous-liste ci-dessous, montrer **toutes les étapes** de `tri_fusion` : les divisions successives, puis les fusions, jusqu'au résultat final.
```python
sous_liste = [
{"nom": "Sandrine", "score": 22},
{"nom": "Kevin", "score": 9},
{"nom": "Bibou", "score": 26},
{"nom": "Chrystel", "score": 20},
]
```
---
### Partie 3 - Comparaison des complexités
| Algorithme | Complexité |
|-----------------|------------|
| Tri par sélection | O(n²) |
| Tri fusion | O(n log n) |
1. Pour **n = 12** prétendant·e·s :
- Combien d'opérations environ pour le tri par sélection ?
- Combien d'opérations environ pour le tri fusion ? *(rappel : log₂(12) ≈ 3,58)*
2. La saison 2 de La Flamme est un succès planétaire. Marc reçoit désormais **1 000 candidatures**.
Calculer l'ordre de grandeur du nombre d'opérations pour chaque algorithme.
Que remarques-tu ?
3. La production doit choisir un algorithme à intégrer dans leur logiciel de classement. Lequel recommandes-tu, et pourquoi ?
---
### Bonus - Marc change d'avis
Marc, dans un élan de narcissisme, décide finalement de classer les prétendant·e·s **par charme décroissant** plutôt que par score.
Modifier la fonction `fusionner` pour trier selon `charme` en ordre **décroissant**. Appliquer le tri fusion modifié à la liste et afficher le classement final.
---
Sources :
- Programme officiel NSI Terminale - Algorithmique
- [La Flamme - Canal+](https://www.canalplus.com/series/la-flamme/)
Auteur : Florian Mathieu - Licence CC BY-SA
\- **Introduction** - un GIF de la cérémonie des roses pour poser le contexte
\- **Avant Partie 1** - Marc qui parcourt tous les prétendant·e·s un par un (tri sélection)
\- **Avant Partie 2** - la scène des deux villas ou une séparation de groupe
\- **Partie 3** - Marc qui s'impatiente avec une longue liste (pour illustrer la complexité)