MPO n°68 : les tours de Hanoï

Ici, on fait dans le petit, le LCD qui déchire sa race, on y cause même calculatrices quand on est en manque !

Modérateur : Politburo

Avatar du membre
Marge
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 6186
Enregistré le : 01 oct. 2008 14:39
Localisation : En bas, tout au fond à gauche.

MPO n°68 : les tours de Hanoï

Message par Marge »

Bonjour, un petit MPO en attendant le réveillon de la saint-Sylvestre, ça vous dit ? attention, celui-ci peut vous emmener fort loin !

Image

Le jeu des tours de Hanoï se prête assez bien à la programmation pour petites machines (il a été imaginé par le mathématicien français Édouard Lucas, et certains d'entre vous l'ont peut-être étudié). Son principe est de déplacer un par un les 9 disques de la tour de gauche vers la tour de droite en prenant garde à ne jamais placer un disque plus grand au-dessus d'un autre.

Pour représenter le jeu sur une calculette, il suffit de posséder trois affichages à 10 chiffres qui peuvent correspondre à des registres de mémoire. On prendra pour convention les trois affichages initiaux suivants :

1.987654321
2.000000000
3.000000000


avec la tour gauche notée 1, la centrale notée 2 et la droite notée 3.

Évidemment, il faut disposer d'une machine à 10 chiffres de mantisse.

Je propose de scinder le problème en deux parties :

1. Il s'agit de programmer la manipulation des disques ; par exemple, si l'affichage montre la tour 1, un appui sur [2] déplacera le disque du sommet de la tour 1 vers la tour 2 ; Édition : le programme ne doit pas s'assurer de la validité du coup, et il n'est pas nécessaire qu'il vérifie si vous avez gagné la partie (ce serait trop difficile pour la pauvre ch'tit' 57...) .
Vous pouvez imaginer tout ce que vous voulez pour ce programme. Je suppose qu'une simple TI-57 y parviendra.

2. Il s'agit de programmer la résolution du problème ! Il y a très certainement quelque littérature à ce sujet sur le Ouèbe, mais essayer de réfléchir d'abord paraît plus intéressant. Là encore, vous pouvez tenter ce que vous voulez, mais je déconseille la TI-57 ! :lol:

À vos machines !

Sommaire des MPO
Modifié en dernier par Marge le 20 sept. 2020 02:29, modifié 1 fois.
3 hommes, 3 demis, un 3a... Magnéto, Serge !

Quelques-uns de mes petits programmes pour machines Hewlett-Packard :
15C : Knight's Tour ;
29C : (k-)Permutations, Combinations, Linear Regression and Pseudo-random number ;
34C : Hanoi Towers - Automatic & Manual resolutions ;
67
__: A L I E N .

« Boris », c'était juste Maurice enrhumé.
Avatar du membre
Marge
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 6186
Enregistré le : 01 oct. 2008 14:39
Localisation : En bas, tout au fond à gauche.

Re: MPO n°68 : les tours de Hanoï

Message par Marge »

Prem's ! :lol:

Ici, le défi n°1 est relevé sur une HP-29c. C'est certainement améliorable, il ne reste que 15 pas libres...
Et encore, on ne vérifie pas la validité du coup (à ce propos, j'ai changé l'énoncé du problème...).

Ce n'est pas très rapide lorsque les tours sont vides... mais le programme est assez complet (84 + 7*7 = 133 octets).

Code : Tout sélectionner

N° | Instruction | Commentaire           N° | Instruction | Commentaire                   N° | Instruction | Commentaire

01   LBL 9         Init. par GSB 9       23   STO 4         Tour visée                    56   LBL 4
02   Clear Reg                           24   Rd            Tour initiale                 57   1
03   GSB 0                               25   LBL 7                                       58   0
04   3                                   26   RCL 0                                       59   STO*5          "Compteur" de boucle
05   STO 3                               27   10^x                                        60   STO*i
06   2                                   28   *                                           61   RCL i
07   STO 2                               29   FRAC                                        62   FRAC
08   1                                   30   X#0 ?          x différent de 0 ?           63   X#0 ?
09   .                                   31   GTO 6                                       64   GTO 4
10   9                                   32   LAST x                                      65   LBL 5
11   8                                   33   RCL 0                                       66   RCL 6          Rappel du disque.
12   7                                   34   10^x                                        67   STO+i
13   6                                   35   /                                           68   RCL 5
14   5                                   36   DSZ            Décrémente R0 et saute       69   STO/i
15   4                                   37   GTO 7          le pas suivant si R0=0,      70   RCL i
16   3                                   38   GTO 7          mais... à éviter !           71   PAUSE          Montre la tour visée.
17   2                                   39   LBL 6                                       72   GSB 0          Lance la reconfiguration.
18   1                                   40   STO 6          Stocke le disque.            73   GTO 8          Disque suivant !
19   STO 1                               41   LAST x                                      74   LBL 0          Routine de reconfiguration.
20   FIX 9                               42   INT                                         75   8
21   LBL 8                               43   RCL 0                                       76   STO 0
22   R/S        Attend le choix          44   10^x                                        77   1
********************************         45   /                                           78   STO 5
T1, T2 & T3 sont en R1, R2 & R3,         46   INT                                         79   RCL 1
mais également dans la pile.             47   STO 0                                       80   RCL 1
Le joueur peut visualiser les 3          48   LAST x                                      81   RCL 2
tours par Rd. La tour affichée           49   STO i          Stocke la tour décapitée.    83   RCL 3
est celle dont sera retiré le            50   RCL 4                                       84   RTN
prochain disque. Le choix de la          51   STO 0
tour réceptrice est déterminé            52   RCL i
par un entier (1, 2 ou 3) stocké         53   FRAC
en R4. R0 & R5 sont des compteurs,       54   X=0 ?
R6 contient le disque à bouger.          55   GTO 5
********************************

Ah, si j'avais la 29E de zpalm, je pourrais certainement relever le défi n°2 !
3 hommes, 3 demis, un 3a... Magnéto, Serge !

Quelques-uns de mes petits programmes pour machines Hewlett-Packard :
15C : Knight's Tour ;
29C : (k-)Permutations, Combinations, Linear Regression and Pseudo-random number ;
34C : Hanoi Towers - Automatic & Manual resolutions ;
67
__: A L I E N .

« Boris », c'était juste Maurice enrhumé.
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2931
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: MPO n°68 : les tours de Hanoï

Message par zpalm »

J'ai le cerveau en vacances en ce moment... voici juste une petite optimisation: on peut gagner 6 pas en remplaçant les pas 8 à 18 par:

Code : Tout sélectionner

08 RCL 2
09 8
10 1
11 1/x
12 -
J'essaierai demain sur ma 29E, mais malgré toutes ses capacités on ne peut avoir de programme de plus de 98 pas.
Avatar du membre
Marge
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 6186
Enregistré le : 01 oct. 2008 14:39
Localisation : En bas, tout au fond à gauche.

Re: MPO n°68 : les tours de Hanoï

Message par Marge »

zpalm a écrit :J'ai le cerveau en vacances en ce moment... voici juste une petite optimisation: on peut gagner 6 pas en remplaçant les pas 8 à 18 par:

Code : Tout sélectionner

08 RCL 2
09 8
10 1
11 1/x
12 -
J'essaierai demain sur ma 29E, mais malgré toutes ses capacités on ne peut avoir de programme de plus de 98 pas.
Ah, très bon ! j'ai passé un moment à chercher des divisions par 11 (sacré gege !), mais c'était une astuce par 1/81 (je l'avais oubliée, celle-là !) ! Merci !

Sur la 29E, si c'est comme sur la 25E, y a-t-il moyen de transférer des données d'une zone programme à une autre ?
Mais j'ai peut-être mal compris... :oops:

Cela dit, je respecte les vacances et le sommeil d'autrui, :D je vais faire du béton pendant 3 jours, alors... ça peut attendre. :wink: (j'édite car c'est repoussé à la semaine prochaine, il pleut depuis deux mois tous les jours ici. Mais ça peut toujours attendre !)
3 hommes, 3 demis, un 3a... Magnéto, Serge !

Quelques-uns de mes petits programmes pour machines Hewlett-Packard :
15C : Knight's Tour ;
29C : (k-)Permutations, Combinations, Linear Regression and Pseudo-random number ;
34C : Hanoi Towers - Automatic & Manual resolutions ;
67
__: A L I E N .

« Boris », c'était juste Maurice enrhumé.
Avatar du membre
gege
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 7147
Enregistré le : 31 janv. 2008 14:24
Localisation : Banlieue Paârisienne
Contact :

Re: MPO n°68 : les tours de Hanoï

Message par gege »

Bonjour,
il me semble que ce problème est bien étudié (le nombre de coups est 2^N pour N disques), par contre si la configuration de départ est "libre", ça semble plus ouvert...
Exemple on démarre avec :
1> 86531
2> 974
3> 2
et il faut aboutir à tout mettre sur le poteau 1> ...
Je vais tenter un algo (pas la moindre idée pour l'instant, génial !)
A+
G.E.
Avatar du membre
Marge
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 6186
Enregistré le : 01 oct. 2008 14:39
Localisation : En bas, tout au fond à gauche.

Re: MPO n°68 : les tours de Hanoï

Message par Marge »

Oui, c'est bien étudié (comme je l'ai dit...), mais j'aime le brut de décoffrage !
Ta formule est incorrecte (de peu).

1 1
2 3
3 7...
3 hommes, 3 demis, un 3a... Magnéto, Serge !

Quelques-uns de mes petits programmes pour machines Hewlett-Packard :
15C : Knight's Tour ;
29C : (k-)Permutations, Combinations, Linear Regression and Pseudo-random number ;
34C : Hanoi Towers - Automatic & Manual resolutions ;
67
__: A L I E N .

« Boris », c'était juste Maurice enrhumé.
Avatar du membre
badaze
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 8402
Enregistré le : 12 févr. 2007 18:36
Localisation : Pas très loin de Lyon
Contact :

Re: MPO n°68 : les tours de Hanoï

Message par badaze »

J'avais fait un algo il n'y a pas si longtemps que ça mais impossible de me souvenir pourquoi ?
Le seul truc dont je me souvienne c'est que c'était récursif.
Tout est bon dans le pocket.
Moi j'aime tout.... Casio, HP, Sharp, TI et les autres sauf que les TI semblent ne pas m'aimer :(
http://www.emmella.fr
Mes Casio - HP - Sharp - TI
Homme invisible.
Avatar du membre
bernouilli92
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 5266
Enregistré le : 21 nov. 2012 13:03
Localisation : Ile de France

Re: MPO n°68 : les tours de Hanoï

Message par bernouilli92 »

Un algo récursif est tout ce qu'il de plus naturel :
Pour deplacer les 9 disques de 1 à 3, il faut :
- déplacer les 8 disques du dessus de la position 1 à la position 2
- déplacer le disque restant en 3
- déplacer les 8 disques de la position 2 à la position 3

Et pour déplacer les 8 disques de 1 à 2, il suffit de :
- déplacer les 7 disques du dessus de 1 à 3
- déplacer le disque restant de 1 à 2
- déplacer les 7 disques de 3 à 2

Etc.

Mais c'est très gourmand en branchements, chaque étape conduit à deux sous-étapes.
HP, Casio, Sharp, Psion, quelques TI et divers autres
Avatar du membre
Marge
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 6186
Enregistré le : 01 oct. 2008 14:39
Localisation : En bas, tout au fond à gauche.

Re: MPO n°68 : les tours de Hanoï

Message par Marge »

bernouilli92 a écrit :Un algo récursif est tout ce qu'il de plus naturel :
Pour deplacer les 9 disques de 1 à 3, il faut :
- déplacer les 8 disques du dessus de la position 1 à la position 2
- déplacer le disque restant en 3
- déplacer les 8 disques de la position 2 à la position 3

Et pour déplacer les 8 disques de 1 à 2, il suffit de :
- déplacer les 7 disques du dessus de 1 à
- déplacer le disque restant de 1 à 2
- déplacer les 7 disques de 3 à 2

Etc.

Mais c'est très gourmand en branchements, chaque étape conduit à deux sous-étapes.
Oui, c'est ça, vu dans l'autre sens. Pour vous consoler, le minimum est de 511 coups. (corrigé)
Modifié en dernier par Marge le 25 oct. 2017 20:51, modifié 1 fois.
3 hommes, 3 demis, un 3a... Magnéto, Serge !

Quelques-uns de mes petits programmes pour machines Hewlett-Packard :
15C : Knight's Tour ;
29C : (k-)Permutations, Combinations, Linear Regression and Pseudo-random number ;
34C : Hanoi Towers - Automatic & Manual resolutions ;
67
__: A L I E N .

« Boris », c'était juste Maurice enrhumé.
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3419
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: MPO n°68 : les tours de Hanoï

Message par C.Ret »

gege a écrit :Bonjour,
il me semble que ce problème est bien étudié (le nombre de coups est 2^N pour N disques), par contre si la configuration de départ est "libre", ça semble plus ouvert...
Exemple on démarre avec :
1> 86531
2> 974
3> 2
et il faut aboutir à tout mettre sur le poteau 1> ...
Je vais tenter un algo (pas la moindre idée pour l'instant, génial !)
A+
G.E.
Pour être compatible avec l'énoncé, le plus simple est de finir par tout mettre sur la tour n°3.

Bon voici ma réponse aux questions 1 & 2 pour un SHARP PC-1211

Les trois tours sont nommées A B et C dans ce programme qui ne fait qu'environ 428 octets et n'utilise aucune variable au-delà de la zone mémoire préétablie aux registres A-Z. Il est donc compatible pour le SHARP PC-1210.

Il répond à la question n°1 car il permet de gérer les déplacements entre les trois tours. Ceci est réalisé à l'aide des trois touches [ A ] [ B ] et [ C ] en mode DEF afin de lancer respectivement les mouvements A<===>B , A<===>C et B<==>C. Le sens du mouvement s'effectuant en fonction de la configuration des deux tours. A savoir depuis la tour remplie vers la tour vide (si les deux tours sont vide un BEEP retenti pour indiquer le mouvement impossible), Si les deux tours sont remplies, le sens utilisé permettra de déplacer le disque le plus petit vers la tour contenant le disque le plus grand.

Ainsi:
def-[ A ] ( A<--->B ) permet le déplacement d'un disque entre les tours A et B. C'est à dire soit de la tour A vers la tour B, soit dans l'autre sens de la tour B vers la tour A.
En effet, s'il y a au moins un disque dans chacune des tours, seul le disque le plus petit est déplacé. Il n'y a donc pas d'ambiguïté, A<===>B correspond à A-->B ou B-->A selon la position du plus grand disque ou que l'une des deux tour soit vide. C'est d'ailleurs une astuce qui facilite l'algorithme de résolution. Et moins de déplacements à programmer dans le code MPO.

De même def-[ B ] et def-[ C ] déclenchent les mouvements A<===>C et B<===>C qui correspondent selon les circonstances aux déplacements du disque de A-->C ou C-->A et respectivement B-->C ou C-->B

En cas de déplacement impossible (les deux tours vides), le pocket sonne et revient à l'affichage de l'étape en cours.

Les lignes 1: et 2: permettent de saisir trois tours initiales quelconques comme le suggère notre am gégé.
Comme pour les TI-57, le contenu des trois tours initiales n'est pas vérifié.

Pour spécifier un nouveau contenus pour les trois tours, il suffit d'utiliser le raccourci def-[SPC] (comme DEFinir SPéCifier !) ou de relancer le programme par RUN[ENTER]
Le pocket demande alors la composition des tours A, B et C. Un simple appuis sur ENTER permet de passer à la tour suivante et revient à saisir 0 (qui signifie tour vide).

En fonction de la parité du nombre de disque, le pocket élabore une stratégie de résolution qui utilise des choses compliquées comme des logarithmes décimaux, deux variables (G et P comme Coup Gagnant et Parité) et un test de division par deux (cf. ligne 3:) ! Il en résulte un algorithme de résolution automatique que l'utilisateur pourra déclencher pas à, pas à chaque étape.

Pour lancer la configuration initiale proposée par Marge, il suffit de n'entrer aucune composition, le code étant par défaut programmé avec cette configuration (cf. ligne 1:).


La réponse à la question n°2 est réalisée par la seconde partie de la ligne 4: qui déroule l'algorithme de résolution automatique grâce à un astucieux GOTO 6+G. Celle-ci est automatiquement lancée en pressant [ENTER]à chaque étape lors de l'affichage du contenu des trois tours. L'utilisateur peut donc après chaque coup tenter d'avancer dans la résolution ou laisser faire son pocket.

J'utilise un algorithme itératif qui revient à déplacer le disque le plus petit toujours dans le même sens en alternance avec le déplacement d'un des autres disques.

A chaque étape, l'affichage du SHARP-PC1211 se compose des informations suivantes :
- nombre de déplacement depuis le début de la partie, (variable N)
- rappel du dernier mouvement (taille du disque, tour d'origine et destination) (resp. variable X E$ et F$)
- contenu de la tour A (variable A) ou 0. si celle-ci est vide
- contenu de la tour B (variable B) ou 0. si celle-ci est vide
- contenu de la tour C (variable C) ou 0. si celle-ci est vide

Exemple affichage initial:

Code : Tout sélectionner

Affichage                  Keystrocke       Commentaires
------------------------  --------------   ----------------------------------------------------------
>                         MODE             Mettre en mode DEF
RUN_                      RUN[ENTER]       Lance le programme 
? _                       [ENTER]          Demande composition Tour A - Aucune saisie (configuration de Marge)
? _                       [ENTER]          Demande composition Tour B - idem  
? _                       [ENTER]          Demande composioton Tour C - idem

 0.1  A987654321.B0.C0.                    Affichage de l'état initial - En cas d'erreur relancer par def-SPC
                                            La tour A contient l'empilement des 9 disques 
                                            B et C sont vides.

Code : Tout sélectionner

                          shft-A           Déplacement entre A et B.
 1.1AB A98765432.B1.C0.                    1. coup
                                           1AB indique que le disque 1 a été déplacé de A vers B
                                           A contient maintenant 98765432, B contient 1  et C est vide. 
                          shft-B           Déplacement entre A et C.
 2.2AC A9876543.B1.C2.    shft-C           Déplacement entre B et C, comme 2 ne peut-être posé sur le 1
                                            c'est ce dernier qui sera déplacé de C-->B.
 3.1BC A9876543.B0.C21.                    La tour B est à nouveau vide.
                          shft-A           Déplacement entre A et B.
 4.3AB A987654.B3.C21.    shft-B           Déplacement entre A et C,ici aussi c'est 1 qui sera déplacé.
 5.1CA A9876541.B3.C2.    shft-B           Répétition du dernier déplacement pour annuler son effet
 6.1AC A987654.B3.C21.                     On retrouve la configuration de l'étape 4.

Code : Tout sélectionner

                          shft-SPC         Ré-initialisation des tours
? 321_                    321[ENTER]       Saisie de la configuration simple pour exemple de résolution
? 0_                      0[ENTER]         
? _                       [ENTER]     
 0.1    A321. B0. C0.      [ENTER]          Petit exemple pour tester l'algorithme de résolution.
 1.1AC  A32. B0.  C1.      [ENTER]
 2.2AB  A3.  B2.  C1.      [ENTER]
 3.1CB  A3.  B21. C0.      [ENTER]
 4.3AC  A0.  B21. C3.      [ENTER]
 5.1BA  A1.  B2.  C3.      [ENTER]
 6.2BC  A1.  B0.  C32.     [ENTER]
 * * beep * beep * beep * *
 7.1AC  A0.B0.C321.                        Résolu en 7 mouvements
PROGRAMME ====================================================================================================

Code : Tout sélectionner

 1:" " CLEAR :USING :A=987654321,D=.1,M=1:FOR I=1 TO 3:INPUT A(I)                                  (43)
 2:IF A(I)>0 GOSUB 5:N=1+N+INT LOG A(I):IF X<M LET M=X,J=I                                         (38)
 3:NEXT I:P=1-2*(N/2<>INT .5N),N=0,G=2J+P                                                          (34)
 4:"=" Y=A+B=0:BEEP 3Y:PRINT N+X,E$,F$," A";A;"B";B;"C";C:G=G-3*INT (G/3):GOTO 6+G                 (63)
 5:X=DA(I),X=X-INT X:RETURN                                                                        (18)
 6:"A" I=1,E$="A",J=2,F$="B":GOTO 9                                                                (30)
 7:"B" I=1,E$="A",J=3,F$="C":GOTO 9                                                                (30)
 8:"C" I=2,E$="B",J=3,F$="C"                                                                       (27)
 9:GOSUB 5:Y=DA(J),Y=Y-INT Y:IF Y IF Y*SGN X<=X LET X=I,I=J,J=X,X$=E$,E$=F$,F$=X$:GOTO 9           (63)
10:G=G+P,Y=1:IF A+B IF X LET N=N+1,A(J)=(A(J)+X)/D,A(I)=INT DA(I),Y=0:IF X<M LET M=X,G=2J+P        (74)
11:BEEP Y:GOTO 4                                                                                   ( 8)
                                                                                                  (428 octets)
LIGNES :==================================================================================================

Code : Tout sélectionner

1:2:3: def-SPC   Initialisation des trois tours et de la stratégie gagnante GP

4:     def- =    Affichage du dernier coup et configuration des trois tours
       [ENTER]    et résolution automatique pas à pas

6:     def- A    Mouvement n°1 A<===>B déplaçant soit de A-->B soit de B-->A selon le contenu des tours
7:     def- B    Mouvement n°2 A<===>C déplaçant un disque de A-->C ou C-->A
8:     def- C    Mouvement n°3 B<===>C déplaçant un disque de B-->C ou C-->B
Sous-Programme :==================================================================================================

Code : Tout sélectionner

5:         Appels depuis ligen 2: et 9: pour extraction du disque X de la tour I
9:10:11:   Tronc commun du transfert du disque X avec éventuel échange par le disque Y de la tour j si celui-ci est plus ptit (ligne 9:)
           La ligne 10: effectue le mouvement du disque et ajoute la stratégie gagnante GP si le disque minium M est manipulé
CODES SONNORES: :==============================================================================================

Code : Tout sélectionner

 1 BEEP est émis en cas d'erreur (mouvement impossible)
 3 BEEP retentissent lorsque la configuration finale est atteinte (tous les disques sur la tour C)
VARIABLES ::==================================================================================================

Code : Tout sélectionner

B - Contenu Tour B
C - Contenu Tour C                                M - Valeur du plus petit disque
                                                  N - Nombre de disque/Nombre de mouvements
D - .1 Constante décimale
                                                  P - Parité/ Sens du mouvement
E$ - Label tour origine du mouvement
F$ - Label tour destination du dernier mouvement  X - Valeur disque tour i
                                                  Y - Valeur disque tour j
G - Prochain coup "gagnant"

I - Indice tour i
J - Indice tour j
Etant donné la structure des ligne 6: 7: et 8:, il est évident que ce programme peut encore être MPO-iser, mais je préfère présenter cette version plus lisible et plus compacte, même si quelques octets sont perdus dans cette zone.


J'oubliais !!!

Bonne Année à toutes et tous !!
Modifié en dernier par C.Ret le 24 oct. 2017 20:22, modifié 3 fois.
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
Avatar du membre
Marge
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 6186
Enregistré le : 01 oct. 2008 14:39
Localisation : En bas, tout au fond à gauche.

Re: MPO n°68 : les tours de Hanoï

Message par Marge »

Reçois toutes mes félicitations, C.Ret !

Je n'ai absolument rien lu pour ne pas influencer ma réflexion, mais je te fais confiance ! J'y reviendrai plus tard. :D
3 hommes, 3 demis, un 3a... Magnéto, Serge !

Quelques-uns de mes petits programmes pour machines Hewlett-Packard :
15C : Knight's Tour ;
29C : (k-)Permutations, Combinations, Linear Regression and Pseudo-random number ;
34C : Hanoi Towers - Automatic & Manual resolutions ;
67
__: A L I E N .

« Boris », c'était juste Maurice enrhumé.
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3419
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: MPO n°68 : les tours de Hanoï

Message par C.Ret »

merci Marge

En jouant avec cette première version, je me rends compte de quelques faiblesses dans la résolution automatique...

.. affaire à suivre
.
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
billaj
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 383
Enregistré le : 09 avr. 2005 17:48
Localisation : Brest
Contact :

Re: MPO n°68 : les tours de Hanoï

Message par billaj »

Bonne idée, les tours de Hanoi ! :D Je n'avais jamais réfléchi à ce problème bien connu, voici ce que j'ai pu faire sans rien lire d'autre que la règle (et de très vagues et lointains souvenirs). C'est juste un programme de résolution, qui ne vérifie rien et doit partir d'une configuration où l'axe source contient toute la tour et les deux autres axes rien du tout. Je ne suis pas assez rompu aux MPO ! :mrgreen:

Passons d'abord en revue les cas les plus simples.

Cas 1 : passer un seul disque du sommet d'une pile à une tige vide ou contenant un disque plus grand.
On déplace directement, lol

Cas 2 : passer une pile de deux disques d'un côté à l'autre.
Passer le disque 1 sur la tige du milieu
Passer le disque 2 sur la tige de droite
Passer le disque 1 sur la tige de droite

Cas 3 : 3 disques
1 droite
2 milieu
1 milieu
3 droite
1 gauche
2 droite
1 droite

On voit bien que c'est un peu récursif. En résumé, on fait une pile au milieu avec tous les disques sauf le dernier, on déplace le dernier à droite, et on déplace le reste de la pile à droite. Pour déplacer le reste de la pile au milieu, on déplace ce reste-1 à droite, l'avant-dernier au milieu, puis le reste-1 au milieu. Le déplacement du reste-1 à droite consistant en : déplacement du r-2 au milieu, de l'avant-avant-dernier à droite, déplacement du r-2 à droite. A chaque étape on a : une colonne source, une colonne tampon pour tout sauf la base, et une colonne destination. Et le parcours en profondeur continue jusqu'au cas où il n'y a qu'un disque à déplacer.

On peut maintenant faire une notation pseudo-codale du truc pour faire apparaître plus clairement l'algo récursif :
Fonction H déplaçant toute une pile d'une hauteur h d'un axe src vers un axe dest en stockant toute la pile sauf la base vers un axe tampon :

Code : Tout sélectionner

H(hauteur (1 minimum), src, dest, tampon)
Si on n'a qu'un disque à déplacer, on le déplace directement :

Code : Tout sélectionner

H(1, src, dest, tampon)=mouvement(src, dest)
Le cas 0 est encore plus commode pour une implémentation récursive compacte : pour déplacer une colonne de hauteur 0, soit rien, hé bien...on ne fait rien ! :mrgreen:

Code : Tout sélectionner

H(0, src, dest, tampon)=rien
Et comme approché par l'exemple ci-dessus, déplacer une colonne de src vers dest consiste à déplacer tout sauf le disque du bas de src vers tampon, le plus gros disque de src vers dest, et le reste de la pile de tampon vers dest :

Code : Tout sélectionner

H(h, src, dest, tampon)=H(h-1, src, tampon, dest), mouvement(src, dest), H(h-1, tampon, dest, src)
Voici donc la première implémentation qui marche pour Casio graphique ou assimilée (chez moi, une fx-6800G) :

A profondeur
B source (0,1,2, c'est l'indice pour indexer sur B)
C dest
D tampon
E premiere des 3 colonnes


Prog 0 fait l'initialisation. Je ne lui ai pas mis l'appel direct à Prog 1 pour gagner un niveau de récursion.

Code : Tout sélectionner

Prog 0 (34 pas) :

9->A:
0->B:
2->C:
1->D:
1.23456789->E:
0->F:
0->G:
Prog 1 fait le vrai boulot.

Code : Tout sélectionner

Prog 1 (179 pas) :

A=0=>Goto 9:
A-1->A:
C+D->D:		D=C+D
D-C->C:		C=D
D-C->D:		D=C
Prog1:
E[D]/10+D+1◢	destination, mais on a inversé C et D pour le sous-appel
E[D]/10+Int(E[B])->E[D]:
E[D]/10+D+1◢
E[B]/10+B+1◢
10Frac(E[B])->E[B]:
E[B]/10+B+1◢
B+C->B:		B=B+C
C+D->C:		C=C+D
D+B-C->D:	D=B
B-D->B:		B=C
C-B->C:		C=D
Prog1:
B+D->D:		D=B+D
D-B->B:		B=D
D-B->D:		D=B, et on est retour à la situation initiale
A+1->A:
Lbl 9:

Quelques remarques :
Bon, je me rends compte que je n'ai pas franchement respecté la consigne...on a le plus petit disque/chiffre au plus proche de la virgule. Je demande l'indulgence du jury. Mon affichage se fait dans l'ordre suivant à chaque boucle : état de la colonne vers laquelle on ajoute un disque (0=gauche, 1=tampon, 2=droite) avant puis après, colonne à laquelle on a retiré ce disque, avant puis après. Déjà, commencer par la colonne qui perd un disque serait plus compréhensible (mais il me faudrait une variable de plus) Et surtout, comme j'ai une machine graphique, je devrais par la suite ajouter un affichage digne de ce nom. :)
Comme on n'a pas de passage de paramètre comme certains nantis, on le simule par des échanges sur les variables B, C, D. Je fais mon malin avec de l'arithmétique pour ne pas utiliser une case mémoire de plus, mais ça me coûte des pas. Et appelle deux remarques :
-même si d'un point de vue logique B, C et D sont des entiers et E, F et G les structures de données (soit E[0], E[1] et E[2]), dans cette implémentation ce ne sont tous que des nombres d'une même taille. Donc je pourrais aussi bien swapper E,F et G au lieu de B,C et D, ça simplifierait un peu le code.
-Ou alors...on peut faire une bidouille que je montrerai au prochain épisode. :wink:

edit : correction du nombre de pas, ajout d'un +1 aux numéros de colonnes pour coller de plus près à l'énoncé
edit2 : le symbole d'affichage, unicode +25E2 est assez approchant...
Modifié en dernier par billaj le 08 janv. 2016 23:23, modifié 2 fois.
Quand Chuck Norris joue à Nintendogs, il a automatiquement armes et munitions infinies.
Chuck Norris peut revenir en arrière dans Super Mario Land.
Chuck Norris utilise exclusiment des calculatrices Texas Instruments.
Avatar du membre
Marge
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 6186
Enregistré le : 01 oct. 2008 14:39
Localisation : En bas, tout au fond à gauche.

Re: MPO n°68 : les tours de Hanoï

Message par Marge »

Bravo billaj ! et bienvenue dans le monde noctambule des MPOïstes (oui, car tu peux y perdre des heures de sommeil... 8) )

Bon comme pour C.Ret, je n'ai rien lu pour m'éviter un échauffement prématuré de la boîte crânienne, et surtout parce que je suis sur l'affaire pour HP-34c... ça avance doucement, mais tant que zpalm n'a rien publié, je suis à l'heure !

Je regarderai ça un peu plus tard ! :D
3 hommes, 3 demis, un 3a... Magnéto, Serge !

Quelques-uns de mes petits programmes pour machines Hewlett-Packard :
15C : Knight's Tour ;
29C : (k-)Permutations, Combinations, Linear Regression and Pseudo-random number ;
34C : Hanoi Towers - Automatic & Manual resolutions ;
67
__: A L I E N .

« Boris », c'était juste Maurice enrhumé.
Avatar du membre
gege
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 7147
Enregistré le : 31 janv. 2008 14:24
Localisation : Banlieue Paârisienne
Contact :

Re: MPO n°68 : les tours de Hanoï

Message par gege »

Bonjour,
Bravo en effet ça a l'air sympathique, finalement on peut bien s'amuser sur une machine bien choisie.
A relire au calme !
G.E.
Répondre

Retourner vers « Tous les Pockets »