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

.128013tf)2r,3sao iugm1Ppnlh.e=cy:v(wS/b_dk050J0x0b0j0m0u0i0l0z0u0j0i0i0y010b0m0s010406050i0n0p0p0j0f0A040F0k0u0n0#0k0t050G0,0.0:0=0*0s040~1505180G181a150*0J0m0C0T0V0X0Z0v0m0o0v0u1o0v0b0(050O0H0u0x1j0W0Y011n1p1r1p0b1x1z1v0b0H0k0J0=1w0f160b0v0T0^0i0s0j0t0Z0e011B1l010c0Q0x0t0j0p0x1v1Z1#1*1D1-1z1:1=0(0a0l0r0f0k0s0k0i0m0{0t0l0M1X0f0f0x0z2a0~1^0t160G1V2n0b1T1S1U0J1`0Z1r0t1/271v1g1i0U1C2x0m2z0t1P1h1v0s2g162l2n2R0+1!2b2F1+2K0f0/0u0(0q2k2V0)2U1_2X1D2Z2#0(0e2)1#2+2l2w012:0j2$040h2@2m172P0~2D2q0J2u2{0z1P1?163719352T0 2*053c0M2Q2V2{0K0(0M0c323p2-1k1D0E0(0l3w2,2W3z0Z0t0c3t0x0s0V0z0x0I2(3k2^3F2{0%040D3E2`2.3I3L1!0f0b3!3q3$013X0g3w3D3#3H2|0(0:0f1h0x0x3,3y2G3/0(0d0B3w060l493?3-3^0t0(0C2~0x0n0f3=3V3.0k0(0y4l3@424e040M3)3+3T334s1+4o040w403G4t3(1.4G3W0(0D0d474a4b412Y3`2f3}3 4z3x4H4C0(4F4Z4m4d0(0x0p0s4K4)4B1D3X3Z4;4c4I044g1z4j4L3.3X4P4Z0*0G3n0x2n2O58361h382q2s2o1O1Q2q0j1y5b0G37550M0O0Q0i04.

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

.1280134tf)2r,3sao iugm1Ppnlhe=cy:v(wS/b_dk050J0x0c0k0n0v0j0m0z0v0k0j0j0y010c0n0t010406050j0o0q0q0k0g0A040F0l0v0o0#0l0u050G0,0.0:0=0*0t040~1505180G181a150*0J0n0C0T0V0X0Z0w0n0p0w0v1o0w0c0(050O0H0v0x1j0W0Y011n1p1r1p0c1x1z1v0c0H0l0J0=1w0g160c0w0T0^0j0t0k0u0Z0f011B1l010d0Q0x0u0k0q0x1v1Z1#1*1D1-1z1:1=0(0a0m0s0g0l0t0l0j0n0{0u0m0M1X0g0g0x0z2a0~1^0u160G1V2n0c1T1S1U0J1`0Z1r0u1/271v1g1i0U1C2x0n2z0u1P1h1v0t2g162l2n2R0+1!2b2F1+2K0g0/0v0(0r2k2V0)2U1_2X1D2Z2#0(0f2)1#2+2l2w012:0k2$040i2@2m0*2`2.0Z2}2 0b322n2O0x2n2D2q0J2u2{0z1P1?163g192P2,2m3b053l0M2Q2V2{0K0(0M0d3u351k1D0E0(0m3F3z362|0d3C0x0t0V0z0x0I2?0 2*3s2{0%040D3M2-3H373R1!0g0c3*2W3,013%0h3b3L3G2G2|0(0:0g1h0x0x3=3$0(3`3Z2^3|3N3@0u0(2I0c0x2!0x1g0P2g463O3%0e0B3b060m4w4c3+3~4f040M3T0k3V0I2(4a3t3}1+3%3)4J3y4z2Y3.0:3;4P3#4q483{4X4e4g0u4i4k4m0n4o4W4L1D4r4u4x4y3?4A3.3U3W4I2T4/0Z4N4p4$4C3S4U523~3_4!4 3 044143454.4d580(0e4=4x4#4_544E4G4}3!5b515h4R2/4%4)1=4+4-4~5i4M4Z4P4@2{4B5e0C44575H045l4P0*0G3w3e173r0G3p2o3i0~2r2q1O1Q2q0k1y5Y5#1h2+5#0N0P0R04.

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

.1280135tf4)2r3,sa-o iugm1P6pnl7he=cy:v(wS/b_dk050N0B0c0l0p0y0k0o0D0y0l0k0k0C010c0p0w010406050k0q0s0s0l0h0E040J0n0y0q0)0n0x050K0:0=0@0_0.0w041219051c0K1c1e190.0N0p0G0X0Z0#0%0A0p0r0A0y1s0A0c0,050S0L0y0B1n0!0$011r1t1v1t0c1B1D1z0c0L0n0N0_1A0h1a0c0A0X0|0k0w0l0x0%0g011F1p010d0U0B0x0l0s0B1z1%1)1.1H1;1D1@1_0,0a0o0u0h0n0w0n0k0p0 0x0o0Q1#0h0h0B0D2e121|0x1a0K1Z2r0c1X1W1Y0N1~0%1v0x1?2b1z1k1m0Y1G2B0p2D0x1T1l1z0w2k1a2p2r2V0/1(2f2J1/2O0h0?0y0,0t2o2Z0-2Y1}2#1H2%2)0,0g2-1)2/2p2A012@0l2*040i2{2q0.2~2=0%31330e362}2Z2 3c0,0b3f383h3a300n2(320,0v3m2:2!1o2?3r2^040z3f1b2T122H2u0N2y2 0D1T1`1a3J1d3H2X132.053O0Q2U3o3z0%0O0,0Q0d3F393%010I0,0o3-3$2K300d3*0B0w0Z0D0B0M113W2|3x2 0+040H3@2;3/0x0,432X3.3_480j3f3?4i2$3|1(0h0c4b3y4j0,4l442q4n3^4p040@0h1l0B0B4u474x4m463p4e042M0c0B2(0B1k0T2k4K3p480f0F3m0o4*4B4c3_3)4R3,4z044,4v4D4g2.4@2 0n0,0C0C4N4o1H0s0p2_4!3/484(4=064+5e4|3p4/2k0c0q0h4`2|5g4d4q3 412`4=4O590,4a5v533b4q0@4t5A4C1H4k525H5C4E2j4H4J5G4-1/5J4=5p3_4Q4S4U1_4X0p4Z5R4^5I0,0f4)4+5w4.0,0B0V5Q4h5L015a5.5f5W4D0Q3~0l4042584w49664_5K5S1H4~040m6b5*0%552+695+044y2V5 2?5D4s6m0%5U6q5:4D5Z4V5$5(5_6c6w4M5V6z6s5N4G0G4I6v5{5,5}5f6K5M615s0M2,5)4L686#4P6t5F6F6i6R6o6h3i0,4F5P6Q4$6T5e6V305r63415n2q6|485z6,6;04714?6|6e6g6J5B016k046!764#6I6y7f5Y0x4T6C0p4Y5^3X7f6x4{6|4Q6?6O7v457x7m7z7o6*6^6S5c123Z0B2r2S7Q3I1l3K2u2w2s1S1U2u0l1C7T0K3J0.7*0R0T0V04.

L'animation se lancera ici

Animation


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