Résolution de la tour de Hanoï

Tour de Hanoï

La tour de Hanoï est un jeu inventé par le mathématicien français Édouard Lucas.

Les règles sont simples :

  • le jeu est organisé autour de trois bâtons de bois que l'on nommera \(a\), \(b\) et \(c\) ;
  • sur ces bâtons, on glisse des pièces circulaires de diamètres différents. Le nombre de pièces est appelé \(n\) ;
  • les pièces doivent toujours être empilées dans un ordre décroissant : il est interdit de poser une grande pièce sur une petite ;
  • à chaque étape on déplace une pièce d'un bâton à l'autre ;
  • initialement, les pièces sont sur le bâton \(a\). Le but du jeu est de les amener sur le bâton \(c\).
A vous de jouer

La partie va bientôt commencer...

Les trois bâtons sont modélisés par des instances de la classe Pile : a, b et c.

Interface de la classe Pile
  • p = Pile() : crée une pile vide et l'affecte à la variable p;

  • p.est_vide() : renvoie le booléen indiquant si la pile p est vide ;

  • p.empile(x) : empile l'élément x dans la pile p;
  • p.depile() : dépile un élément de la pile p si elle n'est pas vide et le renvoie. Provoque une erreur si la pile est vide.
Remarques
  • La classe Pile dispose d'une méthode qui permet de dessiner la pile.

  • La classe empêchera d'empiler une pièce sur une pièce plus petite.

Des pièces de diamètres \(140\), \(120\), \(100\), \(80\), \(60\) et \(40\) sont empilés sur le bâton a. Les bâtons b et c sont initialement vides.

L'état initial
>>> a = Pile()
>>> b = Pile()
>>> c = Pile()
>>> a.empile(140)
>>> a.empile(120)
>>> a.empile(100)
>>> a.empile(80)
>>> a.empile(60)
>>> a.empile(40)
>>> a
'140|120|100|80|60|40|'
>>> b
''
>>> c
''

Les différentes questions sont indépendantes.

Déplacer 1 pièce

Compléter le code de la procédure deplace_1 qui prend en paramètres la pile de depart et la pile d'arrivee, et qui permet de transférer une pièce de l'une vers l'autre.

Exemples

On se place dans l'état initial décrit plus haut. L'exemple ci-dessous permet de déplacer la pièce au sommet de la a sur la b.

>>> deplace_1(a, b)
>>> a
`140|120|100|80|60|`
>>> b
'40|'

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10

.128013ben,vi3mo_tPhklpwf(: cg.a=rySu/)2s1d050K0c0l0z0g0p0I0v0w0p0z0I0I0A010l0g0q010406050I0E0i0i0z0B0C040D0j0p0E0#0j0d050F0,0.0:0=0*0q0405150~180F150*0K0g0f0T0V0X0Z0n0g0x0n0p1m0n0l0(050O0b0p0c1h0W0Y011l1n1p1n0l1v1x1t0l0B160l0n0T0^0I0q0z0d0Z0H011z1j010s0Q0c0d0z0i0c1t1S1U1Z1B1$1x1)1+0(0a0v0m0B0j0q0j0I0g0{0d0v0M1Q0B0B0c0w230~1.0d160F1O2g1L1N1M1u0K1:0Z1p0d1(201t1e1g0U1A2q0g2s0d0j2w1t0q29162e2g2K0+1T242y1!2D0B0/0p0(0J2d2O0)2N1/2Q1B2S2U0(0H2Y1U2!2e2p012)0z2V040h2-2f192I0~2w2j0K1N2o2%0Z0w2E1,1630172~2M0 2Z05370M2J2O2;0o0(0M0s2{3k2$1i1B0r0(0v3r2#2P3u0Z0d0s3o0c0q0V0w0c0k2X3f2.3A2;0%040t3z2:352=3G1T0B0l3V3l3X3S0e3r3y3W3C3Y040:0B1f0c0c3%3t2z013S0G0u3r060v433-3(3/0d0(0f2@0c0E0B3,3Q3X0j0(0A4f3.3|48040M3!3$3O2|4m1!4i040y3`3B4n3Z1%4A3R0(0t0G4144453{2R0(3=3@3_4t3s4B4w0(4z4T4g470(0c0i0q4E4Z4v1B3S3U4+464C044a1x4d4F3)0(4J4T0*0F3i0c2g2H522 1f312j2m2h0z1w550F304 0M0O0Q0I04.

L'animation se lancera ici

Animation

Déplacer 2 pièces

Écrire une procédure deplace_2 qui prend en paramètres \(3\) piles depart, arrivee et intermediaire et qui déplace les \(2\) pièces au sommet du bâton de depart vers le bâton d'arrivee en utilisant le bâton intermediaire.

Exemple

On se place dans l'état initial décrit plus haut. L'appel ci-dessous permet de déplacer les \(2\) pièces au sommet de la pile a vers la pile c, en s'aidant de la pile b comme intermédiaire :

>>> deplace_2(a, c, b)
>>> a
`140|120|100|80|`
>>> b
''
>>> c
'60|40|'

Indication

On pourra réutiliser la procédure deplace_1 qui est déjà chargée en mémoire.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10

.128013ben,4vi3mo_tPhklpwf(: cga=rySu/)2s1d050K0c0m0z0h0q0I0w0x0q0z0I0I0A010m0h0r010406050I0E0j0j0z0B0C040D0k0q0E0#0k0d050F0,0.0:0=0*0r0405150~180F150*0K0h0g0T0V0X0Z0o0h0y0o0q1m0o0m0(050O0b0q0c1h0W0Y011l1n1p1n0m1v1x1t0m0B160m0o0T0^0I0r0z0d0Z0H011z1j010t0Q0c0d0z0j0c1t1S1U1Z1B1$1x1)1+0(0a0w0n0B0k0r0k0I0h0{0d0w0M1Q0B0B0c0x230~1.0d160F1O2g1L1N1M1u0K1:0Z1p0d1(201t1e1g0U1A2q0h2s0d0k2w1t0r29162e2g2K0+1T242y1!2D0B0/0q0(0J2d2O0)2N1/2Q1B2S2U0(0H2Y1U2!2e2p012)0z2V040i2-2f0*2:2%0Z2?2^0f2{2g2H0c2g2w2j0K1N2o2 010x2E1,1639172I2#2f34053g0M2J2O2;0p0(0M0t3p2~1i1B0s0(0w3A3u3e0d0t3x0c0r0V0x0c0l2,0 2Z3n2;0%040u3H2$3C303M1T0B0m3#2P3%013Y0e343G3B2z2=0(0:0B1f0c0c3-3X0(3=3U2.3@3I3/0d0(2B0m0c2T0c1e0P29413e3Y0G0v34060w4r473$3_4a040M3O0z3Q0l2X453o3^1!3Y3!4E3t4u2R3)0:3,4K3W4l433?4S494b0d4d4f4h0h4j4R4G1B4m4p4s4t3.4v3)3P3R4D2M4*0Z4I4k4X4x3N4P4}3_3;4V4`3`043|3~404)48530(0G4-4s4W4;4 4z4B4^3V564|5c4M2(4Y4!1+4$4(4_5d4H4U4K4/2;4w590g3 525C045g4K0*0F3r37193m0F3k2h3b0~2k5!0z1w5T5W1f2!5W0N0P0R04.

L'animation se lancera ici

Animation

Déplacer n pièces

Un stratégie de résolution optimale, qui résout le problème en un nombre minimal de déplacements, repose sur l'observation suivante. Transporter \(n\) pièces du bâton \(a\) vers le \(c\) nécessite de :

  • transporter les \(n - 1\) pièces du dessus du bâton \(a\) vers le \(b\) ;

  • déplacer la plus grande pièce du bâton \(a\) vers le \(c\) ;

  • transporter les \(n - 1\) pièces du bâton \(b\) vers le \(c\).

L'illustration ci-dessous1 illustre la résolution du problème dans le cas \(n = 4\) :

Animation

Écrire une procédure récursive deplace_n qui prend en paramètres le nombre n de pièces à déplacer et \(3\) piles depart, arrivee, intermediaire et qui déplace les n pièces du sommet du bâton de depart vers le bâton d'arrivee en utilisant le bâton intermediaire.

On pourra réutiliser les procédures deplace_1 et deplace_2 qui sont déjà chargées en mémoire.

Aide

Les solutions pour \(n = 1\) et \(n = 2\) sont triviales : voir questions précédentes.

Exemples

On se place dans l'état initial décrit plus haut. L'appel ci-dessous permet de déplacer les \(4\) pièces au sommet du bâton a vers le bâton c, en s'aidant du bâton b comme intermédiaire :

>>> deplace_n(4, a, c, b)
>>> a
`140|120|`
>>> c
'100|80|60|40|'

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10

.128013ben,4vi3mo5_tPhklpwf(: cga=ryS6-u/72)s1d050O0c0n0A0h0r0M0x0y0r0A0M0M0B010n0h0s010406050M0H0j0j0A0C0D040E0k0r0H0)0k0d050I0:0=0@0_0.0s040519121c0I190.0O0h0g0X0Z0#0%0p0h0z0p0r1q0p0n0,050S0b0r0c1l0!0$011p1r1t1r0n1z1B1x0n0C1a0n0p0X0|0M0s0A0d0%0K011D1n010u0U0c0d0A0j0c1x1W1Y1%1F1*1B1-1/0,0a0x0o0C0k0s0k0M0h0 0d0x0Q1U0C0C0c0y27121=0d1a0I1S2k1P1R1Q1y0O1@0%1t0d1,241x1i1k0Y1E2u0h2w0d0k2A1x0s2d1a2i2k2O0/1X282C1(2H0C0?0r0,0N2h2S0-2R1?2U1F2W2Y0,0K2$1Y2(2i2t012-0A2Z040i2;2j0.2@2+0%2`2|0f2 2?2S2^350,0l38313a332_0k2X2{0,0F3f2)2T1m2,3k2.040J381d2M122A2n0O1R2s3i0y2I1:1a3C1b3A2Q132%053I0Q2N3h3s0%0q0,0Q0u3y323X010t0,0x3%3W2D2_0u3!0c0s0Z0y0c0m113Q2=3q2^0+040v3.2*3)0d0,3}2Q3(3:420e383-4c2V3?1X0C0n453r4d0,4f3~2j4h3/4j040@0C1j0c0c4o414r4g403i48042F0n0c2X0c1i0T2d4E3i420L0w3f0x4!4v463:3Z4L3$4t044$4p4x4a2%4.2^0k0,0B0B4H4i1F0j0h2/4U3)424Y4,064#584?3i4)2d0n0H0C4;2=5a474k3_3{2:4,4I530,445p4}344k0@4n5u4w1F4e4|5B5w4y2c4B4D5A4%1(5D4,5j3:4K4M4O1/4R0h4T5L4/5C0,0L4Z4#5q4(0,0c0V5K4b5F01545(595Q4x0Q3^0A3`3|524q43604:5E5M1F4^040G655!0%4 2!635#044s2O5_2,5x4m6g0%5O6k5*4x5T4P5W5Y5:666q4G5P6t6m5H4A0g4C6p5=5$5@596E5G5{5m0m2#5Z4F626V4J6n5z6z6c6L6i6b3b0,4z5J6K4W6N586P2_5l5}3{5h2j6?425t6$6+046{4-6?686a6D5v016e046U704V6C6s795S0d4N6w0h4S5/3R796r4=6?4K6-6I7p3 7r7g7t7i6!6/6M56123T0c2k2L7K3B1j3D2n2q2l0A1A7N0I3C0.7X0R0T0V04.

L'animation se lancera ici

Animation


  1. Les illustrations de cette page proviennent d'ici et