Un corrigé pédagogique pour comprendre et justifier vos réponses. Les conseils de rédaction ne constituent pas un barème officiel détaillé.
Exercice 1 · 6 points
Réseau du lycée : adressage, routage et confidentialité
Le réseau informatique du lycée relie campus, internat et services administratifs. Chaque site possède un sous-réseau avec son propre adressage IP et une interface de routeur qui lui sert de passerelle. Les liaisons entre routeurs sont celles du schéma suivant ; R5 est relié à Internet.
Lire les connexions du schéma
- R1 relié à R2
- R1 relié à R3
- R1 relié à R4
- R2 relié à R3
- R2 relié à R4
- R3 relié à R4
- R4 relié à R5
| Site | Sous-réseau | Routeur |
|---|---|---|
| site1 | 172.16.0.0/20 | R1 |
| site2 | 172.16.16.0/20 | R1 |
| site3 | 172.16.32.0/20 | R2 |
| site4 | 172.16.48.0/20 | R2 |
| site5 | 172.16.64.0/20 | R3 |
| site6 | 172.16.80.0/20 | R3 |
En notation CIDR a.b.c.d/n, les n bits de poids fort identifient le réseau ; les autres identifient la machine. Les machines d’un même sous-réseau partagent leur partie réseau. Convention du lycée : la passerelle prend la dernière adresse utilisable du sous-réseau et cette adresse est affectée à l’interface du routeur côté site. Pour le site6 : réseau 172.16.80.0, passerelle et interface de R3 172.16.95.254.
Partie A : configuration IP du site3
iface eth0 inet static
address 172.16.32.15
netmask 255.255.240.0
gateway 172.16.48.254Question 1
#Convertir sur 32 bits l’adresse IP 172.16.32.15 et le masque 255.255.240.0, sous la forme XXXXXXXX.XXXXXXXX.XXXXXXXX.XXXXXXXX.
Indice
Décomposez chaque octet en puissances de deux ; complétez à gauche avec des zéros.
Comprendre la correction
Adresse IP : 10101100.00010000.00100000.00001111
Masque : 11111111.11111111.11110000.00000000Chaque octet doit garder huit chiffres : 172 = 128 + 32 + 8 + 4 ; 16 = 16 ; 32 = 32 ; 15 = 8 + 4 + 2 + 1. Le masque contient vingt bits à 1 consécutifs, donc le préfixe est /20.
Pour vérifier un octet, additionnez uniquement les poids correspondant aux bits à 1 dans la ligne 128, 64, 32, 16, 8, 4, 2, 1. La séparation par des points facilite cette vérification et évite de perdre les zéros initiaux. Le masque binaire n’est pas une adresse de machine : il indique quels bits de l’adresse sont conservés dans la partie réseau.
Question 2
#Indiquer le nombre d’hôtes que ce réseau peut accueillir et les première et dernière adresses IP utilisables.
Indice
Repérez les deux combinaisons réservées : tous les bits hôtes à 0 et tous à 1.
Comprendre la correction
Il reste 32 - 20 = 12 bits pour les hôtes. On obtient 2¹² - 2 = 4 094 adresses utilisables, de 172.16.32.1 à 172.16.47.254. 172.16.32.0 désigne le réseau et 172.16.47.255 la diffusion. La passerelle consomme elle-même une de ces 4 094 adresses si l’on compte les autres équipements à installer.
Dans le troisième octet, les quatre bits de poids fort sont fixes : 0010. Ses quatre bits de poids faible vont de 0000 à 1111, ce qui donne les valeurs 32 à 47. Le dernier octet varie de 0 à 255. Le premier hôte est donc obtenu après l’adresse tout à zéro côté machine, et le dernier avant l’adresse tout à un. Cette méthode fonctionne aussi lorsqu’un masque ne s’arrête pas sur une frontière d’octet.
Question 3
#L’hôte accède aux serveurs et imprimantes du site3, mais pas à Internet. Un test vers 172.16.47.254 réussit. Identifier le paramètre erroné et proposer une correction.
Indice
Une passerelle IPv4 directement accessible doit être dans le sous-réseau de l’hôte.
Comprendre la correction
La passerelle configurée 172.16.48.254 appartient au site4, hors du sous-réseau de l’hôte. Remplacer par gateway 172.16.47.254. Une communication locale n’utilise pas la passerelle ; cela explique pourquoi imprimantes et serveurs restent joignables. Le test confirme que l’interface attendue de R2 est accessible.
Question 4
#Le lien R2-R4 utilise le réseau 192.168.0.8/30. Proposer deux adresses pour les interfaces des routeurs.
Indice
Un /30 contient quatre adresses, dont deux sont utilisables.
Comprendre la correction
Par exemple R2 : 192.168.0.9 et R4 : 192.168.0.10, ou l’inverse. Les quatre adresses vont de .8 à .11 ; .8 est le réseau et .11 la diffusion.
Partie B : routage dynamique
Depuis un hôte du site3, l’administrateur obtient :
$ traceroute education.gouv.fr
1 4 ms 7 ms 9 ms R2 [172.16.47.254]
2 22 ms 6 ms 8 ms R3 [192.168.0.14]
3 22 ms 7 ms 9 ms R4 [192.168.0.6]
4 21 ms 6 ms 8 ms R5 [192.168.0.1]
5 19 ms 7 ms 9 ms internet-router [...]
6 ...RIP attribue à une route un coût égal au nombre de liens empruntés.
Question 5
#En RIP, donner le chemin suivi de R2 à R5 d’après cette trace et son coût.
Indice
Comptez les liens, pas les sommets.
Comprendre la correction
R2 → R3 → R4 → R5, coût 3 : trois liens entre routeurs. L’hôte et le routeur Internet apparaissent dans la trace, mais ne font pas partie du trajet demandé de R2 à R5.
Question 6
#Expliquer le dysfonctionnement et proposer une cause possible.
Indice
Cherchez dans le schéma un chemin de deux liens.
Comprendre la correction
Le trajet R2 → R4 → R5 coûte seulement 2 en RIP. Si toutes les liaisons indiquées sont opérationnelles et les tables convergées, la route observée de coût 3 n’est donc pas optimale. Une panne ou mauvaise configuration de R2-R4, une route non annoncée ou une convergence RIP encore inachevée peut l’expliquer. La trace seule ne permet pas d’identifier laquelle.
Le réseau utilise maintenant OSPF avec la formule du sujet coût = 10⁸ / débit.
Question 7
#Pour une liaison, préciser si l’on souhaite minimiser ou maximiser le débit et le coût.
Indice
Le débit mesure une capacité ; le coût est une métrique de choix de route.
Comprendre la correction
On souhaite maximiser le débit et minimiser le coût. Avec la formule donnée coût = 10⁸ / débit, augmenter le débit réduit le coût. Il faut exprimer le débit en bits par seconde, pas directement en Mbit/s.
| Liaison | Technologie | Débit |
|---|---|---|
| R1-R2 | Fast Ethernet | 100 Mbit/s |
| R1-R3 | Fibre optique | 4 Gbit/s |
| R1-R4 | Fast Ethernet | 100 Mbit/s |
| R2-R3 | Ethernet | 10 Mbit/s |
| R2-R4 | Ethernet | 10 Mbit/s |
| R3-R4 | Fibre optique | 4 Gbit/s |
| R4-R5 | Fibre optique | 4 Gbit/s |
Question 8
#Donner le chemin d’un paquet du site4 vers Internet et préciser son coût.
Indice
Le chemin avec le moins de sauts ne possède pas forcément le coût OSPF minimal.
Comprendre la correction
Les coûts sont 10 en Ethernet, 1 en Fast Ethernet et 0,025 pour la fibre (10⁸/(4 × 10⁹)). Du site4, on rejoint R2, puis R2 → R1 → R3 → R4 → R5 → Internet. Le coût inter-routeurs vaut 1 + 0,025 + 0,025 + 0,025 = 1,075. R2-R4-R5 coûterait 10,025 et R2-R1-R4-R5 coûterait 2,025. Les coûts des liaisons site4-R2 et R5-Internet ne sont pas fournis : on ne les invente pas. On applique ici la métrique théorique du sujet, sans arrondi entier propre à certains équipements réels.
Partie C : sécuriser les échanges
Un élève de l’internat, dans le site2, ouvre un logiciel malveillant. Le pirate contrôle son ordinateur et accède au réseau du lycée. Alice, dans le site4, et Bob, dans le site5, commencent ensuite une conversation privée.
Question 9
#Entre chiffrement symétrique et asymétrique, lequel Alice et Bob doivent-ils préférer pour que le pirate ne connaisse pas le contenu des échanges ? Justifier.
Indice
Le point délicat est de partager une clé secrète quand l’attaquant est déjà présent.
Comprendre la correction
Pour établir un échange alors qu’aucun secret préalable n’est indiqué, ils utilisent un mécanisme asymétrique avec authentification des clés : chacun peut publier sa clé publique sans dévoiler sa clé privée. Envoyer une clé symétrique en clair sur le réseau compromis ne la garderait pas secrète. Une fois un secret établi de façon sûre, un chiffrement symétrique convient parfaitement aux données et est employé en pratique. L’asymétrique seul ne suffit pas contre un pirate actif qui substituerait des clés : certificats ou autre vérification fiable de l’identité sont nécessaires. Si Alice et Bob disposaient déjà d’une clé symétrique partagée secrètement, elle pourrait aussi protéger leur conversation.
Question 10
#Expliquer pourquoi HTTPS protège mieux les échanges que HTTP.
Indice
Distinguez confidentialité, intégrité et authentification.
Comprendre la correction
HTTPS transporte HTTP dans TLS. Il fournit le chiffrement des données en transit, le contrôle de leur intégrité et l’authentification du serveur par un certificat validé. HTTP seul laisse les messages lisibles sur le trajet et ne fournit pas ces garanties. Cela ne protège pas un terminal lui-même compromis et ne signifie pas automatiquement que le serveur ne peut pas lire la conversation : le chiffrement de bout en bout serait une propriété supplémentaire.
RIP et OSPF : le même réseau, deux décisionsUn atelier pour expérimenter
Choisissez le protocole et simulez une coupure du lien direct R2-R4. Suivez le trajet retenu jusqu’à R5 et comparez saut et coût.
Lire le résultat de l’expérience initiale
R2 → R1 → R3 → R4 → R5
Les coûts sont additionnés sur les liens empruntés. La destination R5 est la sortie du lycée ; aucun coût R5-Internet n’est donné.
| Liaison | Coût utilisé |
|---|---|
| R1-R2 | 1 |
| R1-R3 | 0.025 |
| R1-R4 | 1 |
| R2-R3 | 10 |
| R2-R4 | 10 |
| R3-R4 | 0.025 |
| R4-R5 | 0.025 |
RIP minimise les sauts ; OSPF minimise une somme de coûts qui favorise les liaisons rapides.
Exercice 2 · 6 points
Recto-Verso : jouer avec XOR et chercher la victoire dans un graphe
Le solitaire Recto-Verso dispose neuf jetons sur un plateau de trois lignes et trois colonnes. Chaque jeton est Recto (noir, représenté par 1) ou Verso (blanc, représenté par 0). Une configuration est l’état de ces neuf jetons. Voici la figure 1, reconstruite avec les mêmes faces :
| Ligne | Colonne 1 | Colonne 2 | Colonne 3 |
|---|---|---|---|
| 1 | ○ Verso | ○ Verso | ● Recto |
| 2 | ○ Verso | ○ Verso | ● Recto |
| 3 | ● Recto | ● Recto | ○ Verso |
Question 1
#Justifier que le nombre total de configurations est 2⁹.
Indice
Comptez les choix successifs pour chacun des neuf emplacements.
Comprendre la correction
Les neuf jetons ont chacun deux états, indépendamment des autres. Le principe multiplicatif donne 2 × 2 × … × 2, avec neuf facteurs, soit 2⁹ = 512 configurations. Ce décompte concerne tous les plateaux, pas uniquement ceux atteignables depuis un plateau donné.
La victoire consiste à obtenir tous les jetons Recto. Un coup retourne tous les jetons d’une ligne, d’une colonne ou de l’une des deux diagonales, soit huit coups. La figure 2 montre ces possibilités depuis la configuration 67 (001/000/011) :
| Ligne | Colonne 1 | Colonne 2 | Colonne 3 |
|---|---|---|---|
| 1 | ○ Verso | ○ Verso | ● Recto |
| 2 | ○ Verso | ○ Verso | ○ Verso |
| 3 | ○ Verso | ● Recto | ● Recto |
| Coup | Plateau obtenu | Entier |
|---|---|---|
| ligne 1 | 110/000/011 | 387 |
| ligne 2 | 001/111/011 | 123 |
| ligne 3 | 001/000/100 | 68 |
| colonne 1 | 101/100/111 | 359 |
| colonne 2 | 011/010/001 | 209 |
| colonne 3 | 000/001/010 | 10 |
| diagonale 1 | 101/010/010 | 338 |
| diagonale 2 | 000/010/111 | 23 |
Question 2
#Depuis la figure 1, la séquence ligne 1, ligne 2, colonne 2 mène-t-elle à la victoire ? Justifier.
Indice
Retourner un jeton noir le rend blanc ; il ne suffit pas de noircir ceux qui étaient blancs.
Comprendre la correction
Non. Les configurations successives sont les suivantes :
| Étape | Ligne 1 | Ligne 2 | Ligne 3 |
|---|---|---|---|
| Départ | 001 | 001 | 110 |
| ligne 1 | 110 | 001 | 110 |
| ligne 2 | 110 | 110 | 110 |
| colonne 2 | 100 | 100 | 100 |
La configuration finale est 292 ; seuls les trois jetons de la première colonne sont noirs. La victoire serait 111/111/111, soit 511.
On code Recto par 1 et Verso par 0. La configuration 67 a pour liste [0, 0, 1, 0, 0, 0, 0, 1, 1], lue comme une écriture binaire.
Question 3
#En détaillant le calcul, donner l’entier représentant la configuration de la figure 1.
Indice
Les zéros initiaux ne changent pas la valeur mais conservent les neuf positions du plateau.
Comprendre la correction
On lit les cases ligne par ligne, de gauche à droite et de haut en bas : 001001110. La valeur est 2⁶ + 2³ + 2² + 2¹ = 64 + 8 + 4 + 2 = 78. Le premier jeton correspond à 2⁸ et le dernier à 2⁰.
Question 4
#Implémenter representant, qui prend une liste de 0 et de 1 et renvoie l’entier correspondant.
Indice
Pour passer du préfixe binaire 101 à 1011, on calcule 2 × 5 + 1.
Comprendre la correction
def representant(bits):
valeur = 0
for bit in bits:
valeur = 2 * valeur + bit
return valeurAprès chaque itération, valeur représente le préfixe déjà lu. Ajouter un bit à droite double la valeur précédente puis ajoute ce bit. On évite ainsi les erreurs sur les exposants et les conversions implicites de chaîne.
| Bit lu | Valeur avant | Calcul | Valeur après |
|---|---|---|---|
| 1 | 0 | 2×0+1 | 1 |
| 0 | 1 | 2×1+0 | 2 |
| 1 | 2 | 2×2+1 | 5 |
Cette trace sur [1,0,1] montre l’invariant du préfixe. Une liste de zéros garde la valeur 0 ; une liste vide donne également 0 selon ce code, même si un plateau du jeu contient toujours neuf bits. Ajouter le bit à la fin plutôt qu’au début est essentiel pour respecter le poids fort placé à gauche.
La fonction binaire est disponible : elle renvoie les neuf bits d’un entier. XOR vaut 1 si ses deux bits diffèrent et 0 sinon.
| X | Y | X ⊕ Y |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
def xor(b1, b2):
if b1 == b2:
return 0
else:
return 1Question 5
#Implémenter xor_etendu(l_x, l_y), renvoyant la liste XOR de deux listes de bits de même longueur.
Indice
Utilisez la fonction xor fournie sur deux bits, pour chaque position.
Comprendre la correction
def xor_etendu(l_x, l_y):
resultat = []
for i in range(len(l_x)):
resultat.append(xor(l_x[i], l_y[i]))
return resultatLes deux listes sont parcourues au même indice. La précondition garantit leurs longueurs égales. Une nouvelle liste est construite : les configurations d’origine ne sont pas modifiées. Pour [1, 1] et [0, 1], on obtient [1, 0].
Le XOR de deux bits est symétrique, mais il faut conserver les positions des cases. Une addition ordinaire ne convient pas : 1+1 vaut2 alors que 1 XOR1 vaut0. On peut tester la réversibilité du résultat : appliquer deux fois xor_etendu avec le même masque doit rendre exactement la liste initiale. Le résultat doit aussi conserver la longueur de l’entrée et ne contenir que0 ou1.
X ⊕ 1 inverse X et X ⊕ 0 le conserve. La figure 3 représente donc chaque transition de la figure 2 par un XOR avec le masque du coup. Voici tous les calculs :
| Coup | Masque | 67 XOR masque |
|---|---|---|
| ligne 1 | 111000000 | 110000011 |
| ligne 2 | 000111000 | 001111011 |
| ligne 3 | 000000111 | 001000100 |
| colonne 1 | 100100100 | 101100111 |
| colonne 2 | 010010010 | 011010001 |
| colonne 3 | 001001001 | 000001010 |
| diagonale 1 | 100010001 | 101010010 |
| diagonale 2 | 001010100 | 000010111 |
coups_possibles = {
"ligne 1": [
1,
1,
1,
0,
0,
0,
0,
0,
0
],
"ligne 2": [
0,
0,
0,
1,
1,
1,
0,
0,
0
],
"ligne 3": [
0,
0,
0,
0,
0,
0,
1,
1,
1
],
"colonne 1": [
1,
0,
0,
1,
0,
0,
1,
0,
0
],
"colonne 2": [
0,
1,
0,
0,
1,
0,
0,
1,
0
],
"colonne 3": [
0,
0,
1,
0,
0,
1,
0,
0,
1
],
"diagonale 1": [
1,
0,
0,
0,
1,
0,
0,
0,
1
],
"diagonale 2": [
0,
0,
1,
0,
1,
0,
1,
0,
0
]
}def configurations_suivantes(config):
config_bin = ...
voisins = []
for ... in ...:
... # ligne facultative
... = xor_etendu(..., ...)
voisins.append(representant(...))
return voisinsQuestion 6
#Recopier et compléter configurations_suivantes pour renvoyer les huit configurations accessibles en un coup.
PythonCalculer huit coups possibles, pas huit coups successifsÉcrivez votre solution et mettez-la à l’épreuve
Écrivez configurations_suivantes(config). config est un entier de 0 à 511 représentant les neuf cases de Recto-Verso, poids fort en haut à gauche. binaire, xor_etendu, representant et coups_possibles sont fournis. Renvoyez les huit configurations obtenues en jouant une seule fois chaque masque sur le même plateau initial. Les tests comparent les ensembles de voisins sans imposer un ordre de parcours.
def configurations_suivantes(config):
# À vous de jouer
passLes cas de test proposés :
- Tout est verso : Depuis zéro, chaque voisin est le nombre représenté par le masque lui-même.
- La configuration 67 du sujet : La première diagonale donne 338 ; les sept autres voisins proviennent eux aussi de 67.
- Tout est recto : XOR retourne les cases visées : un 1 rencontré avec un masque 1 devient 0, il ne reste pas 1.
- Un seul bit de poids fort : Le bit de poids fort vaut 256 et occupe la première case, pas la dernière.
- Conserver les masques pour le prochain appel : Aucun masque n’est un plateau mutable à réutiliser comme accumulateur. Les huit sorties sont distinctes pour ces huit masques.
Indice
Parcourir un dictionnaire fournit ses clés. Récupérez ensuite la liste associée au coup.
Comprendre la correction
def configurations_suivantes(config):
config_bin = binaire(config)
voisins = []
for coup in coups_possibles:
masque = coups_possibles[coup]
suivante = xor_etendu(config_bin, masque)
voisins.append(representant(suivante))
return voisinsUn bit de masque à 1 retourne la case ; un bit à 0 la préserve. Les huit coups sont appliqués chacun au même plateau de départ, et non successivement au plateau obtenu précédemment. Pour 67, la diagonale 1 donne 338, conformément au résultat binaire et au dictionnaire du sujet.
La conversion vers neuf bits se fait une seule fois avant la boucle. Chaque masque produit une nouvelle liste, ensuite convertie en entier. Les huit résultats forment les voisins du sommet config dans le graphe. Une erreur fréquente serait de remplacer config_bin par suivante à chaque tour : cela décrirait une suite de huit coups, alors que la question demande huit alternatives de premier coup.
Partie B : graphe des configurations
Un sommet représente une configuration ; une arête x → y existe lorsqu’un coup autorisé transforme x en y. La victoire est 511. Une configuration perdante n’a aucun chemin vers 511 ; les autres sont gagnantes. Le sujet affirme que 4 est perdante. Le graphe est stocké par dictionnaire :
graphe = {
0: [...],
# ...
67: [387, 123, 68, 359, 209, 10, 338, 23],
# ...
}Question 7
#Montrer que l’existence d’une arête x → y implique celle d’une arête y → x.
Indice
Quel effet a une même ligne retournée deux fois ?
Comprendre la correction
Si le coup de masque m fait passer de x à y, alors y = x ⊕ m. Jouer à nouveau le même coup donne (x ⊕ m) ⊕ m = x : chaque jeton concerné est retourné deux fois. Le coup inverse est donc autorisé et l’arête retour existe.
Question 8
#Comparer le nombre d’entiers nécessaires au stockage par dictionnaire et par matrice d’adjacence, et justifier le choix du dictionnaire.
Indice
Il y a 512 sommets et exactement huit coups distincts depuis chacun.
Comprendre la correction
La matrice comporte 512² = 2¹⁸ entrées. Les listes du dictionnaire contiennent 512 × 8 = 2¹² voisins. En comptant aussi les 512 clés entières, cela fait 2¹² + 2⁹ = 4 608 entiers, contre 262 144 entrées. On ignore ici le surcoût propre aux objets Python, puisque la question demande un nombre d’entiers. Le graphe est peu dense : conserver uniquement les huit voisins par sommet évite les très nombreux zéros de la matrice.
def parcours_profondeur(graphe, configuration, vus):
vus.append(...)
for s in ...:
if s not in vus:
parcours_profondeur(..., ..., ...)Question 9
#Recopier et compléter le parcours en profondeur donné.
Indice
Le premier argument reste le graphe entier ; seul le sommet courant change.
Comprendre la correction
def parcours_profondeur(graphe, configuration, vus):
vus.append(configuration)
for s in graphe[configuration]:
if s not in vus:
parcours_profondeur(graphe, s, vus)On marque le sommet avant ses appels récursifs. Tous les appels partagent la même liste vus, ce qui empêche de tourner indéfiniment sur les cycles. Le parcours modifie la liste et n’a pas besoin de renvoyer une valeur.
Par exemple, sur un triangle A-B-C-A, le premier appel marque A ; quand la récursion atteint C et retrouve A parmi ses voisins, le test d’appartenance le bloque. Si le marquage avait lieu après les appels aux voisins, A pourrait être rappelé avant d’être marqué et le cycle ne serait plus arrêté. La liste vus est un objet partagé, ce qui rend visibles les ajouts des appels profonds.
Question 10
#Utiliser parcours_profondeur pour vérifier que 4 est perdante.
Indice
La cible est 111111111 en binaire, pas la configuration 0.
Comprendre la correction
vus = []
parcours_profondeur(graphe, 4, vus)
print(511 not in vus) # affiche TrueLe parcours liste exactement la composante accessible depuis 4. La configuration entièrement noire vaut 2⁹ - 1 = 511. Son absence prouve qu’aucune suite de coups ne mène à la victoire. Tester seulement les huit voisins ne suffirait pas : il faut inclure les suites de plusieurs coups.
Question 11
#Quel parcours est le plus approprié pour trouver une victoire en un minimum de coups : largeur ou profondeur ? Justifier.
Indice
Une file explore les distances par couches.
Comprendre la correction
Le parcours en largeur explore d’abord les configurations à un coup, puis à deux coups, etc. Chaque arête représente un coup de même coût : la première découverte de 511 fournit donc une distance minimale. On peut mémoriser les prédécesseurs pour reconstruire la suite de coups. Le parcours en profondeur trouve un chemin éventuel, sans garantir qu’il soit le plus court.
Retourner les jetons et trouver une route vers 511Un atelier pour expérimenter
Jouez sur les configurations du sujet : retournez les jetons, suivez l’encodage binaire et cherchez les neuf faces noires. Vous pouvez ensuite demander au parcours en largeur de trouver un chemin minimal, ou d’expliquer pourquoi la victoire est inaccessible.
Lire le résultat de l’expérience initiale
67 → 387 avec ligne 1
Depuis le résultat, une solution minimale est : colonne 1, colonne 3, diagonale 1.
| Case | Avant | Masque | Après |
|---|---|---|---|
| 1 | 0 | 1 | 1 |
| 2 | 0 | 1 | 1 |
| 3 | 1 | 1 | 0 |
| 4 | 0 | 0 | 0 |
| 5 | 0 | 0 | 0 |
| 6 | 0 | 0 | 0 |
| 7 | 0 | 0 | 0 |
| 8 | 1 | 0 | 1 |
| 9 | 1 | 0 | 1 |
XOR rend chaque coup réversible. L’accessibilité et le minimum de coups sont deux questions de graphe différentes.
Exercice 3 · 8 points
Plateforme de débats : arbres d’arguments et base relationnelle
Une plateforme organise les contributions sous forme arborescente plutôt que dans un simple fil chronologique. Chaque affirmation peut recevoir des arguments pour ou contre, qui sont eux-mêmes des affirmations. Le sujet de débat est le point de départ. Dans la figure originale, le sujet est un parallélogramme, les arguments pour des rectangles arrondis et les arguments contre des hexagones ; les mentions ci-dessous rendent ces rôles explicites. Les deux parties sont indépendantes.
- Sujet : La Science est une activité humaine objective.
- Pour : La Science se base sur les faits, qui sont objectifs par définition.
- Contre : Les faits observés restent interprétés par des scientifiques.
- Pour : Les théories scientifiques constituent une généralisation des faits, qui va au-delà des simples faits observés.
- Contre : Les faits observés restent interprétés par des scientifiques.
- Pour : La Science promeut l’objectivité dans sa méthode.
- Pour : La méthode scientifique s’efforce de corriger les biais existants.
- Contre : La Science est faite par des humains, qui ont leur propre subjectivité.
- Contre : Les théories scientifiques établies se vérifient quelles que soient les personnes qui les appliquent.
- Contre : La Science subit des pressions sociales et institutionnelles qui compromettent son objectivité.
- Pour : La recherche financée par des organismes commerciaux peut tordre les faits.
- Pour : Les géants pétroliers ont minimisé l’impact de l’effet de serre causé par les énergies fossiles.
- Pour : Les méfaits du tabagisme sur la santé ont longtemps été sous-estimés par des médecins.
- Contre : La recherche dispose de financements publics la mettant à l’abri des pressions du privé.
- Contre : La communauté scientifique elle-même est une institution qui fait valoir l’objectivité scientifique.
- Pour : La recherche financée par des organismes commerciaux peut tordre les faits.
- Pour : La Science se base sur les faits, qui sont objectifs par définition.
Chaque affirmation peut recevoir des likes et des dislikes.
Question 1
#Comment appelle-t-on le point de départ du débat dans le vocabulaire des arbres ?
Indice
Ce nœud domine tous les autres.
Comprendre la correction
C’est la racine de l’arbre : l’unique nœud qui n’a pas de parent.
Question 2
#Un arbre de débat est-il nécessairement binaire ? Justifier.
Indice
Comptez les enfants de la racine dans la figure.
Comprendre la correction
Non. Dans un arbre binaire, chaque nœud a au plus deux enfants. Ici, le sujet possède quatre arguments directs ; un nombre quelconque d’arguments peut être ajouté. Deux catégories, pour et contre, ne signifient pas deux enfants.
class Affirmation:
def __init__(self, phrase):
"""Création d'un objet Affirmation à partir d'une phrase (str)."""
self.contenu = phrase
self.sorte = "" # "sujet", "pour", "contre" ; vide avant ajout
self.arguments = []
self.nb_likes = 0
self.nb_dislikes = 0Question 3
#Donner le nom et le type de chaque attribut de la classe Affirmation.
Indice
Les attributs sont les valeurs affectées à self.nom.
Comprendre la correction
| Attribut | Type | Rôle |
|---|---|---|
| contenu | str | Phrase de l’affirmation |
| sorte | str | sujet, pour, contre ou chaîne vide avant insertion |
| arguments | list | Liste d’objets Affirmation enfants |
| nb_likes | int | Nombre de likes |
| nb_dislikes | int | Nombre de dislikes |
phrase est un paramètre du constructeur ; ce n’est pas un attribut conservé sous ce nom. self désigne l’instance.
def soutenir(self, argument):
"""Ajoute argument comme argument pour de self.
Précondition : argument ne doit pas avoir été utilisé
comme sujet, pour ou contre ; son attribut sorte le vérifie.
"""
assert argument.sorte == ...
... .append(argument)
argument.sorte = "..."On dispose aussi d’une méthode contrer similaire qui ajoute un argument contre.
Question 4
#Compléter les lignes 10 à 12 de soutenir conformément à sa documentation.
Indice
La chaîne vide indique un objet encore inutilisé.
Comprendre la correction
assert argument.sorte == ""
self.arguments.append(argument)
argument.sorte = "pour"On vérifie que l’argument n’appartient pas encore à l’arbre, on l’ajoute à la liste des enfants de l’affirmation courante, puis on enregistre son rôle. Modifier self.sorte serait une erreur : c’est le nouvel argument qui soutient son parent.
Question 5
#Écrire la méthode nb_contre, qui compte les arguments contre directement rattachés à cette affirmation.
Indice
Filtrez la liste des enfants sur leur attribut sorte.
Comprendre la correction
def nb_contre(self):
nombre = 0
for arg in self.arguments:
if arg.sorte == "contre":
nombre += 1
return nombreOn ne parcourt que les enfants directs. La consigne ne demande pas le nombre de contre-arguments dans tout le sous-arbre ; il ne faut donc pas ajouter d’appel récursif ici.
Une affirmation peut avoir un argument pour qui possède lui-même plusieurs arguments contre. Ceux-ci ne sont pas directement rattachés à l’affirmation de départ et ne doivent pas être comptés dans cette méthode. Ce décompte local est précisément la valeur que mystere comparera ensuite à celles des autres nœuds.
def mystere(self):
m = self.nb_contre()
for arg in self.arguments:
candidat = arg.mystere()
if candidat > m:
m = candidat
return mQuestion 6
#Expliquer en une phrase ce que renvoie mystere.
Indice
Repérez le maximum calculé entre la valeur locale et les résultats des appels récursifs.
Comprendre la correction
Elle renvoie le plus grand nombre d’arguments contre directs rattachés à une même affirmation dans le sous-arbre de l’affirmation courante, celle-ci comprise. Le maximum commence avec self.nb_contre(), puis est comparé au maximum de chacun des sous-arbres. Ce n’est ni un total de contre-arguments ni une hauteur.
L’évaluation additionne les likes de l’affirmation et les évaluations de ses arguments pour ; elle soustrait ses dislikes et les évaluations de ses arguments contre. Un résultat positif favorise le pour, un résultat négatif le contre. Lignes proposées :
def evaluation(self):
def evaluation():
total = self.nb_likes + self.nb_dislikes
total = self.nb_likes - self.nb_dislikes
total = self.nb_dislikes - self.nb_likes
total = self.nb_likes * self.nb_dislikes
for arg in self.arguments:
for arg in self.arguments_pour:
for arg in self.arguments_contre:
if arg.sorte == "sujet":
if arg.sorte == "pour":
if arg.sorte == "contre":
else:
total = arg.evaluation()
total = total + arg.evaluation()
total = total - arg.evaluation()
total = total * arg.evaluation()
return total
return 1 + totalQuestion 7
#En choisissant uniquement les lignes proposées et en adaptant l’indentation, écrire evaluation.
Indice
Traduisez la formule locale puis remplacez chaque contribution enfant par un appel récursif.
Comprendre la correction
def evaluation(self):
total = self.nb_likes - self.nb_dislikes
for arg in self.arguments:
if arg.sorte == "pour":
total = total + arg.evaluation()
else:
total = total - arg.evaluation()
return totalUne feuille renvoie simplement likes - dislikes. Pour un nœud interne, chaque soutien ajoute son évaluation et chaque opposition la soustrait. Soustraire une opposition d’évaluation négative augmente le score du parent : un argument contre lui-même fortement contesté peut renforcer l’affirmation. Le else convient car un enfant inséré est pour ou contre, jamais sujet.
Prenons un sujet de score local5, un soutien évalué3 et une opposition évaluée-2. L’évaluation du sujet vaut5+3-(-2)=10. Pour obtenir le3 ou le-2 des enfants, la même méthode évalue d’abord tous leurs descendants. Il s’agit donc d’un calcul ascendant : les feuilles fournissent leur différence likes/dislikes, puis chaque parent combine ces valeurs avec le signe du lien. La récursion se termine car l’arbre possède un nombre fini de niveaux.
Partie B : utilisateurs et contributions
La plateforme gère plusieurs débats avec un SGBD. On peut employer SELECT, FROM, WHERE, AND, OR, JOIN ... ON, ainsi que INSERT, UPDATE et DELETE.
Question 8
#Quelles propositions font partie des rôles d’un SGBD ? a) Sécuriser les accès ; b) Assurer l’alimentation électrique des serveurs ; c) Assurer la persistance des données même en cas de panne matérielle ; d) Gérer les accès parallèles de plusieurs utilisateurs ; e) Assurer des connexions HTTPS au serveur.
Indice
Séparez la gestion des données de l’alimentation et du serveur web.
Comprendre la correction
Réponses attendues : a, c et d. Le SGBD gère les droits d’accès, la durabilité et la récupération via journaux/sauvegardes, ainsi que les accès concurrents. L’alimentation relève de l’infrastructure et HTTPS du service réseau/web. La durabilité n’est pas une garantie magique contre toute destruction physique : elle suppose les mécanismes de stockage, de sauvegarde et de reprise adaptés.
Le schéma de la figure 2 est reconstruit ci-dessous. La clé primaire est indiquée explicitement, et chaque référence correspond à une clé étrangère :
| Table | Attributs | Clé primaire | Clés étrangères |
|---|---|---|---|
| utilisateur | pseudo, email, nom, prenom | pseudo | - |
| affirmation | id_aff, contenu, auteur, sorte, aff_repondue, nb_likes, nb_dislikes | id_aff | auteur → utilisateur.pseudo ; aff_repondue → affirmation.id_aff |
| reaction | aff_reagie, utilisateur, sorte | (aff_reagie, utilisateur) | aff_reagie → affirmation.id_aff ; utilisateur → utilisateur.pseudo |
Une affirmation est de sorte sujet, pour ou contre. Une réponse référence son parent par aff_repondue ; un sujet a NULL. Son texte est contenu. Une réaction, like ou dislike, porte sur aff_reagie. Extraits (auteur et contenu non affichés) :
| id_aff | sorte | aff_repondue | nb_likes | nb_dislikes |
|---|---|---|---|---|
| 0 | sujet | NULL | 42 | 17 |
| 1 | pour | 0 | 20 | 20 |
| 2 | pour | 0 | 40 | 10 |
| 3 | contre | 0 | 13 | 12 |
| 4 | contre | 0 | 18 | 6 |
| 7 | contre | 1 | 15 | 16 |
| aff_reagie | utilisateur | sorte |
|---|---|---|
| 0 | alice | like |
| 1 | alice | dislike |
| 0 | bob | dislike |
| 1 | bob | dislike |
Question 9
#Quel autre attribut de utilisateur aurait aussi pu servir de clé primaire ? Justifier.
Indice
Une clé primaire doit être unique et ne pas être NULL.
Comprendre la correction
L’attribut email, à condition que la plateforme impose une adresse renseignée et unique par compte, peut identifier chaque utilisateur. C’est l’alternative usuelle visée. Le schéma seul ne déclare cependant pas cette contrainte : sans elle, son statut de clé candidate n’est pas démontré. Ni le nom ni le prénom ne garantissent l’unicité.
Question 10
#Écrire la requête donnant le nombre d’affirmations ayant 50 likes ou plus.
Indice
Le sujet rappelle que COUNT(*) compte les lignes du résultat.
Comprendre la correction
SELECT COUNT(*)
FROM affirmation
WHERE nb_likes >= 50;WHERE filtre d’abord les affirmations ; COUNT(*) compte ensuite les lignes retenues. L’égalité doit être incluse. Le résultat est un nombre unique, pas une liste de likes.
Question 11
#Obtenir les contenus des sujets et leurs nombres de likes, créés par les utilisateurs prénommés Pierre et nommés Durand.
SQLDistinguer les sujets de débat de leurs réponsesÉcrivez votre solution et mettez-la à l’épreuve
Affichez contenu et nb_likes des affirmations de sorte égale à 'sujet' écrites par les utilisateurs dont le prénom est Pierre et le nom Durand. Plusieurs comptes peuvent porter ce nom complet.
SELECT ...
FROM ...
WHERE ...;Les cas de test proposés :
- Structure de l’extrait, auteurs explicitement ajoutés : Les compteurs 42/17 et 20/20 ainsi que les identifiants 0 et 1 viennent de l’extrait. Le PDF omet leurs auteurs et contenus : ceux-ci et les comptes nécessaires sont donc des compléments pédagogiques.
- Cas complémentaire : homonymes et deux filtres d’identité : Jeu complémentaire pédagogique, distinct des données officielles. Deux affirmations distinctes produisent les mêmes valeurs projetées : elles doivent rester deux lignes. Chaque partie du nom complet est nécessaire.
Indice
Le lien entre les deux tables est auteur = pseudo. Le filtre sujet reste indispensable.
Comprendre la correction
SELECT a.contenu, a.nb_likes
FROM affirmation AS a
JOIN utilisateur AS u ON a.auteur = u.pseudo
WHERE a.sorte = 'sujet'
AND u.prenom = 'Pierre'
AND u.nom = 'Durand';La jointure associe l’auteur à son compte par la clé, puis les trois conditions doivent être vraies simultanément. On ne suppose pas que le couple nom/prénom identifie une seule personne ; tous les sujets des homonymes correspondants sont retournés.
Pour relire la requête, imaginez les étapes logiques : la jointure produit les couples affirmation/auteur compatibles ; les trois filtres retiennent les sujets écrits par les personnes portant les deux noms demandés ; le SELECT ne conserve que contenu et nb_likes. Cette lecture distingue bien le rôle de chaque clause et permet de détecter un oubli du filtre sorte.
Le mot-clé AS donne un alias à une table. Le sujet fournit exactement :
SELECT aff.contenu, rep.contenu
FROM affirmation AS aff JOIN affirmation AS rep
ON rep.affirmation_repondue = aff.id_affirmation
WHERE rep.nb_likes >= 2 * aff.nb_likes
AND rep.sorte = 'contre'Question 12
#Interpréter en français la requête ci-dessous.
Indice
Interprétez aff comme l’affirmation parent et rep comme la réponse.
Comprendre la correction
L’intention est d’obtenir le texte d’une affirmation et le texte d’une réponse contre cette affirmation, lorsque cette réponse possède au moins deux fois autant de likes que l’affirmation. Les deux alias distinguent le parent et sa réponse. Le SQL imprimé utilise toutefois deux noms absents du schéma : affirmation_repondue et id_affirmation. Pour l’exécuter avec les tables données, la jointure doit être rep.aff_repondue = aff.id_aff. Sans cette correction, la requête échoue ; ce n’est pas une difficulté de compréhension de votre part.
... reaction
VALUES (..., ..., ...);
... affirmation
SET nb_likes = ...
WHERE ... = ...;Question 13
#L’utilisateur i<3descartes aime l’affirmation Cogito ergo sum, d’identifiant 108. Compléter les deux requêtes de mise à jour.
Indice
Il faut conserver la valeur actuelle du compteur puis lui ajouter un.
Comprendre la correction
INSERT INTO reaction
VALUES (108, 'i<3descartes', 'like');
UPDATE affirmation
SET nb_likes = nb_likes + 1
WHERE id_aff = 108;La première instruction mémorise la réaction dans l’ordre des attributs de la table. La seconde incrémente le compteur existant, sans le remplacer par 1, et ne concerne que l’affirmation 108. On suppose qu’aucune réaction de ce compte sur cette affirmation n’existait déjà, conformément à l’insertion demandée. En application réelle, ces deux opérations seraient regroupées dans une transaction.
Le compte i<3rgpd demande l’effacement de ses données. La procédure du sujet conserve les affirmations en remplaçant leur auteur par NULL, supprime toutes les réactions du compte sans modifier les compteurs de likes/dislikes, puis supprime le compte. On suit cette procédure technique imposée ; elle n’est pas une analyse juridique générale de l’anonymisation.
Question 14
#Pourquoi supprimer les réactions avant le compte utilisateur ?
Indice
Quel attribut de reaction référence le compte à supprimer ?
Comprendre la correction
Chaque réaction référence utilisateur.pseudo par une clé étrangère. Supprimer d’abord le compte laisserait des références sans ligne cible et violerait l’intégrité référentielle, en l’absence d’une suppression en cascade prévue. Les affirmations doivent de même avoir été anonymisées avant la suppression du compte.
Question 15
#Écrire les trois requêtes de suppression des données de i<3rgpd, conformément à la procédure.
Indice
D’abord casser les références au compte, ensuite supprimer la ligne référencée.
Comprendre la correction
UPDATE affirmation
SET auteur = NULL
WHERE auteur = 'i<3rgpd';
DELETE FROM reaction
WHERE utilisateur = 'i<3rgpd';
DELETE FROM utilisateur
WHERE pseudo = 'i<3rgpd';Cet ordre préserve les clés étrangères. NULL s’écrit sans guillemets : ce n’est pas une chaîne contenant le mot NULL. Les likes et dislikes restent inchangés, car le sujet le demande explicitement. Les clauses WHERE évitent de toucher les autres utilisateurs.
Une opposition contestée peut-elle renforcer le débat ?Un atelier pour expérimenter
Réglez le score local du sujet et celui d’un argument. Changez le rôle pour/contre : observez la différence entre le score de l’argument et sa contribution au parent.
Lire le résultat de l’expérience initiale
Évaluation du sujet : 33
Une opposition est soustraite. Si elle est évaluée négativement, soustraire ce score ajoute une contribution positive.
| Élément | Valeur |
|---|---|
| Score local | 25 |
| Score de l’argument | -8 |
| Contribution après prise en compte du rôle | 8 |
La récursion calcule d’abord la valeur du sous-arbre ; le parent applique ensuite le signe correspondant au lien.
Revoir les notions de cet exercice
Du sujet à la méthode
Votre prochaine séance de révision
- Pour les réseaux, écrivez les unités des débits avant de calculer les coûts.
- Pour le solitaire, conservez neuf bits afin de garder la correspondance entre indices et cases.
- Dans un programme récursif, identifiez la valeur locale et la combinaison des résultats enfants.
- En SQL, relisez les noms du schéma : le sujet contient une incohérence signalée à la question 12.
Retrouver ces notions dans d’autres sujets
Toutes les annales de NSI · Le guide pour préparer le bac NSI 2027
Énoncé : sujet 26-NSIJ1ME1 (PDF). Corrigé et explications pédagogiques proposés par Sofien.
