Exercice 1 Asie – Bac NSI 2026 – Jour 2
mots clés: POO, structures linéaires
🔎 Voir les exercices similaires ↓
Asie – Bac NSI 2026 – Jour 2 Énoncé de l'exercice 1
Cet exercice porte sur la programmation orientée objet et les structures linéaires.
Le taquin est un casse-tête qui se joue avec une grille de 9 cases : une case vide et 8 cases numérotées de 1 à 8.
Le jeu démarre en position gagnante représentée comme sur la figure 1.

Les cases situées directement à gauche ou à droite ou en-dessous ou au-dessus de la case vide peuvent permuter avec elle. Afin de jouer au jeu taquin, on mélange la grille et l’objectif est de retrouver la position gagnante. On donne ci-dessous un exemple de grille mélangée.

Par exemple, à partir de la situation de la figure 2, seules les cases numérotées 5, 1 ou 7 peuvent permuter leur position avec celle de la case vide.
On représente la grille d’un taquin à l’aide d’un tableau (type list en Python) dont les éléments sont les numéros des cases de la grille de gauche à droite et de haut en bas, la case vide portant le numéro 0. Le tableau ci-dessous contient les numéros de cases de la grille de la figure 2 :
tab = [5, 3, 8, 0, 1, 2, 7, 6, 4]
Donner l’indice de l’élément de tab correspondant à la case portant le numéro 2 de la grille.
Dessiner la grille du taquin représentée par tab après l’exécution des instructions ci-dessous :
1 tab[3] = tab[4]
2 tab[4] = 0
Écrire une expression booléenne qui est évaluée à True si le taquin représenté par le tableau tab est en position gagnante et False sinon.
On souhaite utiliser une classe Taquin pour modéliser le jeu du taquin. On initialise cette classe de la façon suivante :
1 class Taquin:
2 def __init__(self):
3 self.tab = [0, 1, 2, 3, 4, 5, 6, 7, 8]
Écrire la méthode est_gagnant de la classe Taquin qui renvoie True si l’instance de Taquin est en position gagnante et False sinon.
Voici le code partiel de la méthode indice qui renvoie l’indice de l’élément de l’attribut tab qui a pour valeur numero :
1 def indice(self, numero):
2 assert type(numero) == int, 'numero doit être entier'
3 ... , 'numero de case non valide'
4 i = 0
5 while ... :
6 i = i + 1
7 return i
Recopier et compléter les lignes 3 et 5 de la méthode indice.
On admet que la classe Taquin dispose d’une méthode est_possible qui prend en paramètre un entier numero, compris entre 1 et 8 inclus, et qui renvoie True s’il est possible de déplacer la case portant ce numéro et False sinon.
Recopier et compléter les lignes 2 à 6 de la méthode jouer ci-après qui, s’il est possible de déplacer le numéro passé en paramètre, intervertit la case portant ce numéro et la case vide.
1 def jouer(self, numero):
2 if ... :
3 i = self.indice(numero)
4 j = self.indice(0)
5 ... = numero
6 ... = ...
On admet que la classe Taquin possède une méthode coups_possibles qui renvoie un tableau dont les éléments sont les numéros des cases déplaçables. Si t est une instance de la classe Taquin qui correspond à celui de la figure 2, t.coups_possibles() renverra [5, 1, 7].
On importe le module random et on rappelle que, si tab est du type list, l’instruction random.choice(tab) renvoie au hasard un élément de tab.
Pour mélanger n fois le taquin, on choisit au hasard successivement n fois un numéro parmi les coups possibles. On décide de ne pas jouer deux fois de suite le même numéro.
Recopier et compléter les lignes 4, 5, 6 et 9 de la méthode melanger donnée ci-dessous.
1 def melanger(self, n):
2 precedent = None
3 i = 0
4 while ... :
5 possibilites = ...
6 choix = ...
7 if choix != precedent:
8 self.jouer(choix)
9 precedent = ...
10 i = i + 1
On souhaite ajouter à l’implémentation du jeu de taquin un mode résolution automatique lors duquel le jeu jouera une série de numéros afin de revenir en position gagnante. On procède ainsi :
au départ, la grille est en position gagnante, on initialise une pile vide et l’instance de la classe Taquin n’est pas en mode résolution automatique ;
si l’instance n’est pas en mode résolution automatique, on empile les coups joués pour mélanger la grille ainsi que les coups joués par un joueur ;
si l’instance est en mode résolution automatique, tant que le taquin n’est pas gagnant, on dépile la pile et on joue le coup associé.
Par exemple, à partir d’une grille en position gagnante, on considère que les numéros 1, 4 et 5 ont été joués dans cet ordre pour mélanger la grille. Ensuite le joueur a joué le numéro 2 puis a passé le jeu en mode résolution automatique.
Donner, pour la grille issue de l’exemple ci-dessus, les numéros des cases joués dans l’ordre lors de la résolution automatique en précisant à chaque étape l’état de la pile.
On dispose d’une classe Pile dont les méthodes sont est_vide, empiler et depiler. La méthode est_vide renvoie True si la pile est vide et False sinon. La méthode empiler prend en paramètre une valeur et l’empile dans la pile. La méthode depiler dépile une valeur de la pile si elle n’est pas vide et la renvoie.
On modifie l’initialisation de la classe Taquin de la façon suivante :
1 class Taquin:
2 def __init__(self):
3 self.tab = [0, 1, 2, 3, 4, 5, 6, 7, 8]
4 self.pile = Pile()
5 self.mode_resolution = False
On ajoute à la fin du code de la méthode jouer les deux lignes ci-dessous afin d’empiler les coups à chaque appel de cette méthode si l’instance du jeu n’est pas en mode résolution automatique :
7 if not self.mode_resolution:
8 self.pile.empiler(numero)
Lorsque le joueur souhaite avoir la résolution automatique, il appelle la méthode resoudre qui :
passe en mode résolution automatique en donnant la valeur True à l’attribut mode_resolution ;
à chaque étape de la résolution automatique, affiche le coup joué.
Écrire le code de la méthode resoudre.
Expliquer pourquoi l’oubli du passage en mode résolution automatique dans la méthode resoudre entraînerait sa non terminaison.
Jouer deux fois de suite le même numéro est inutile. Pour éviter de stocker dans la pile deux tels coups, on souhaite modifier la méthode jouer.
Si l’instance du jeu taquin n’est pas en mode résolution automatique alors :
si la pile du taquin n’est pas vide alors :
on récupère le numéro au sommet de la pile ;
si ce numéro et celui qu’on vient de jouer sont différents alors on les empile tous les deux dans le bon ordre, sinon on ne fait rien ;
sinon, on empile le numéro qu’on vient de jouer.
Proposer une modification de la méthode jouer à partir de la ligne 8 afin de prendre en compte cette optimisation.
Asie – Bac NSI 2026 – Jour 2 Correction de l'exercice 1
1. Indice de la case numéro 2
tab = [5, 3, 8, 0, 1, 2, 7, 6, 4] : la valeur 2 est à l’indice 5.
2. Grille après les deux instructions
tab[3] = tab[4] copie le 1 à l’indice 3, puis tab[4] = 0 place la case vide à l’indice 4 : tab vaut [5, 3, 8, 1, 0, 2, 7, 6, 4]. Le 1 a glissé vers la gauche :
| 5 | 3 | 8 |
|---|---|---|
| 1 | 2 | |
| 7 | 6 | 4 |
3. Position gagnante
tab == [0, 1, 2, 3, 4, 5, 6, 7, 8]
4. Méthode est_gagnant
def est_gagnant(self):
return self.tab == [0, 1, 2, 3, 4, 5, 6, 7, 8]
5. Méthode indice (lignes 3 et 5)
def indice(self, numero):
assert type(numero) == int, 'numero doit être entier'
assert 0 <= numero <= 8, 'numero de case non valide' # ligne 3
i = 0
while self.tab[i] != numero: # ligne 5
i = i + 1
return i
6. Méthode jouer (lignes 2 à 6)
def jouer(self, numero):
if self.est_possible(numero):
i = self.indice(numero)
j = self.indice(0)
self.tab[j] = numero
self.tab[i] = 0
7. Méthode melanger (lignes 4, 5, 6 et 9)
def melanger(self, n):
precedent = None
i = 0
while i < n: # ligne 4
possibilites = self.coups_possibles() # ligne 5
choix = random.choice(possibilites) # ligne 6
if choix != precedent:
self.jouer(choix)
precedent = choix # ligne 9
i = i + 1
▶ Animation : le taquin et sa pile de coups
Cliquez sur une case voisine de la case vide pour la déplacer, ou mélangez. Chaque coup est empilé ; si l’on rejoue le numéro du sommet, les deux coups s’annulent (optimisation de la question 11). « Résoudre » dépile et rejoue les coups jusqu’à la position gagnante.
pile (base → sommet) :
8. Résolution automatique de l’exemple
Après le mélange (1, 4, 5) et le coup du joueur (2), la pile contient, de la base au sommet : [1, 4, 5, 2]. On dépile et on joue chaque coup :
| coup joué | pile après le coup (base → sommet) |
|---|---|
| 2 | [1, 4, 5] |
| 5 | [1, 4] |
| 4 | [1] |
| 1 | [] : le taquin est gagnant |
Les numéros joués sont donc 2, 5, 4, 1 : les coups dans l’ordre inverse.
9. Méthode resoudre
def resoudre(self):
self.mode_resolution = True
while not self.est_gagnant():
coup = self.pile.depiler()
self.jouer(coup)
print(coup)
10. Oubli du mode résolution
Sans passer en mode résolution, la méthode jouer réempile chaque coup qu’on vient de dépiler. On dépile x, on le joue, on réempile x ; au tour suivant on redépile x et on le rejoue, ce qui annule le coup précédent. La pile ne se vide jamais et le taquin oscille entre deux positions : la boucle while ne se termine pas.
11. Modification de jouer à partir de la ligne 8
if not self.mode_resolution: # ligne 7
if not self.pile.est_vide():
sommet = self.pile.depiler()
if sommet != numero:
self.pile.empiler(sommet)
self.pile.empiler(numero)
else:
self.pile.empiler(numero)
Une erreur, un oubli ? Écrivez-moi : frederic.peuriere@lfcl.pt
🔎 Exercices sur des thèmes similaires
-
Centres étrangers 2026 – jour 2 – exercice 3
architecture matérielle (dont le langage assembleur), structures linéaires de données, POO — Difficulté : 🔥🔥🔥🔥🔥 -
Amérique du Nord 2024 – jour 2 – exercice 3
POO, structures de données, réseaux, architecture matérielle — Difficulté : 🔥🔥🔥🔥🔥 -
Polynésie 2023 – jour 1 – exercice 3
algorithmique, POO, méthode diviser-pour-régner — Difficulté : 🔥🔥🔥🔥🔥 -
Polynésie 2023 – jour 1 – exercice 2
processus, POO — Difficulté : 🔥🔥🔥🔥🔥 -
Polynésie 2023 – jour 2 – exercice 1
arbres binaires de recherche, POO, récursivité — Difficulté : 🔥🔥🔥🔥🔥 -
Métropole 2023 – jour 1 – exercice 3
POO, algorithmique — Difficulté : 🔥🔥🔥🔥🔥