Si vous ne savez pas ce qu'est la Tour de Hanoi , je vais l'expliquer brièvement: il y a trois tiges et quelques disques dont chacun a une taille différente. Au début, tous les disques se trouvent sur la première tour, dans l'ordre trié: le plus gros est en bas, le plus petit en haut. Le but est d'amener tous les disques sur la troisième tige. Cela semble facile? Voici le hic: vous ne pouvez pas placer un disque sur un disque plus petit que l'autre disque; vous ne pouvez tenir qu'un disque dans votre main à la fois pour les déplacer vers une autre tige et vous ne pouvez placer le disque que sur des tiges, pas sur la table, espèce de salaud sournois.
exemple de solution ascii:
A B C
| | |
_|_ | |
__|__ | |
A B C
| | |
| | |
__|__ _|_ |
A B C
| | |
| | |
| _|_ __|__
A B C
| | |
| | _|_
| | __|__
Défi
Il y a trois tiges appelées A, B et C. (Vous pouvez aussi les appeler 1,2 et 3 respectivement si cela vous aide) Au début, tous les n disques sont sur la tige A (1).
Votre défi est de vérifier une solution pour la tour de hanoi. Vous devrez vous assurer que:
- Au final, tous les n disques se trouvent sur la tige C (3).
- Pour un disque donné à un état donné, il n'y a pas de disque plus petit en dessous.
- Pas d'erreurs évidentes comme essayer de retirer des disques d'une tige vide ou déplacer des disques vers des tiges inexistantes.
(la solution ne doit pas être optimale.)
Contribution
Votre programme recevra deux entrées:
- Le nombre de disques n (un entier)
Les mouvements qui sont effectués, qui seront constitués d'un ensemble de tuples de: (tour pour prendre le disque actuellement le plus haut), (tour pour prendre ce disque) où chaque tuple fait référence à un mouvement. Vous pouvez choisir comment ils sont représentés. Par exemple quelque chose comme les façons suivantes de représenter la solution pour n = 2 que j'ai dessinée ci-dessus en ascii. (Je vais utiliser le premier dans les cas de test, car il est doux pour les yeux):
"A-> B; A-> C; B-> C"
[("A", "B"), ("A", "C"), ("B", "C")]
[(1,2), (1,3), (2,3)]
"ABACBC"
[1,2,1,3,2,3]
Sortie
C'est vrai, si les conditions qui peuvent être trouvées sous "défi" tiennent.
Faux, s'ils ne le font pas.
Cas de test:
Vrai:
n=1, "A->C"
n=1, "A->B ; B->C"
n=2, "A->B ; A->C ; B->C"
n=2, "A->C ; C->B ; A->C ; B->C"
n=2, "A->C ; A->B ; C->B ; B->A ; B->C ; A->C"
n=3, "A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; A->C"
n=4, "A->B ; A->C ; B->C ; A->B ; C->A ; C->B ; A->B ; A->C ; B->C ; B->A ; C->A ; B->C ; A->B ; A->C ; B->C"
Faux:
3e proposé par @MartinEnder, 7e par @Joffan
n=1, "A->B"
n=1, "C->A"
n=2, "A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; A->C"
n=2, "A->B ; A->C ; C->B"
n=2, "A->C ; A->B ; C->B ; B->A"
n=2, "A->C ; A->C"
n=3, "A->B ; A->D; A->C ; D->C ; A->C"
n=3, "A->C ; A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; A->C"
n=3, "A->C ; A->B ; C->B ; A->B ; B->C ; B->A ; B->C ; A->C"
n=3, "A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; C->B"
n=4, "A->B ; A->C ; B->C ; A->B ; C->A ; C->B ; A->B ; A->C ; B->C ; B->A ; C->A ; B->C ; A->B ; A->C"
n=4, "A->B ; A->B ; A->B ; A->C ; B->C ; B->C ; B->C"
C'est le code-golf , la solution la plus courte l'emporte. Des règles et des lacunes standard s'appliquent. Pas de piles incluses.
A=1
-àB=2
-dC=3
.,,, Etc.)?A->A
?moving discs to nonexistant rods.
donc bien sûr que oui, c'est unD
Réponses:
Rétine ,
8480 octets-5 octets grâce à Martin Ender
Essayez-le en ligne! (plus 5 octets pour les tests ligne par ligne)
Le code simule un jeu complet.
ACABCBACBABCAC~~~
.~~~
signifie trois disques.ACABCBACBABCAC ~~~ ~~ ~ABC
.Au début, la tige A a les 3 disques et les tiges B et C sont vides.
Dans l' exemple sur, après la première étape, le texte ressemblera:
~CABCBACBABCAC ~~~ ~~ABC
.ABCBACBABCAC ~~~ ~~AB ~C
.la source
Rétine ,
167165157150 150123 octetsCela ressemble totalement à un défi qui devrait être résolu avec une seule expression régulière ... (malgré l'en-tête disant "Retina", ce n'est qu'une expression régulière .NET vanille, correspondant à des entrées valides).
Le format d'entrée est la liste des instructions du formulaire
AB
, suivien
en unaire en utilisant le chiffre1
. Il n'y a pas de séparateurs. La sortie est1
valide et0
invalide.Essayez-le en ligne! (Les deux premiers caractères activent une suite de tests séparés par des sauts de ligne.)
Solution alternative, même nombre d'octets:
Cela peut éventuellement être raccourci en utilisant
1
,11
et111
au lieu deA
,B
etC
je devrai y réfléchir plus tard. Il pourrait également être plus court de diviser le programme en plusieurs étapes, mais où est le défi? ;)Explication
Cette solution fait un usage intensif des groupes d'équilibrage de .NET. Pour une explication complète, consultez mon article sur Stack Overflow , mais l'essentiel est que la capture de groupes dans .NET sont des piles, où chaque nouvelle capture pousse une autre sous-chaîne et où il est également possible de revenir à partir d'une telle pile. Cela vous permet de compter différentes quantités dans une chaîne. Dans ce cas, il nous permet d'implémenter les trois tiges directement en trois groupes de capture différents où chaque disque est représenté par une capture.
Pour déplacer les disques entre les tiges, nous utilisons une bizarrerie étrange de la
(?<A-B>...)
syntaxe. Normalement, cela extrait une capture de la pileB
et pousse sur la pileA
la chaîne entre cette capture éclatée et le début de ce groupe. Donc, une(?<A>a).(?<B-A>c)
correspondance contreabc
laisseraitA
vide etB
avecb
(par opposition àc
). Cependant, en raison des regards croisés de longueur variable .NET, il est possible que les captures de(?<A>...)
et(?<B-A>...)
se chevauchent. Pour une raison quelconque, si c'est le cas, l' intersection des deux groupes est pousséeB
. J'ai détaillé ce comportement dans la "section avancée" sur l'équilibrage des groupes dans cette réponse .Sur le regex. Rods
A
,B
etC
correspondent à des groupes3
,4
et5
dans le regex. Commençons par initialiser la tigeA
:Par exemple, si l'entrée se termine par
111
, le groupe 3 / rodA
contiendra désormais la liste des captures[111, 11, 1]
(le haut étant à droite).Le bit suivant du code a la structure suivante:
Chaque itération de cette boucle traite une instruction. La première alternance tire un disque de la tige donnée (sur un groupe temporaire), la deuxième alternance met ce disque sur l'autre tige donnée. Nous verrons dans un instant comment cela fonctionne et comment nous assurer que le déménagement est valide.
Tout d'abord, retirer un disque de la tige source:
Cela utilise le comportement étrange d'intersection de groupe que j'ai décrit ci-dessus. Notez que groupe
3
,4
et5
aura toujours sous - chaînes de1
s à la fin de la chaîne dont la longueur correspond à la taille du disque. Nous utilisons maintenant(?<1-N>.+)
pour extraire le disque supérieur de la pileN
et pousser l'intersection de cette sous-chaîne avec la correspondance.+
dans la pile1
. Étant donné que.+
couvre toujours nécessairement la capture entière sautéeN
, nous savons que cela déplace simplement la capture.Ensuite, nous mettons ce disque de la pile
1
sur la pile correspondant à la deuxième tige:Notez que nous n'avons pas à nettoyer la pile
1
, nous pouvons simplement laisser le disque là, car nous en mettrons un nouveau avant de réutiliser la pile. Cela signifie que nous pouvons éviter la(?<A-B>...)
syntaxe et simplement copier la chaîne avec(\1)
. Pour nous assurer que le mouvement est valide, nous utilisons l'anticipation négative(?!\N)
. Cela garantit que, à partir de la position où nous voulons faire correspondre le disque actuel, il est impossible de faire correspondre le disque déjà sur la pileN
. Cela ne peut se produire que si a)\N
ne correspondra jamais car la pile est complètement vide ou b)the disc on top of stack
Nis larger than the one we're trying to match with
\ 1`.Enfin, tout ce qui reste est de s'assurer que a) nous avons correspondu à toutes les instructions et b) les tiges
A
etB
sont vides, de sorte que tous les disques ont été déplacésC
.Nous vérifions simplement que ni
\3
ne\4
peut égaler ( ce qui est le cas que si les deux sont vides, parce que tout disque réel serait correspondre) et que nous pouvons alors correspondre à une1
sorte que nous n'omis aucune instruction.la source
Java "uniquement"
311 272 263 261 260 259256 octets39octets innombrables enregistrés grâce à @Frozn remarquant une ancienne fonctionnalité de débogage ainsi que quelques astuces de golf intelligentes.Version golfée
non golfé avec explication et jolies piles imprimées à chaque étape
La version non golfée a une fonctionnalité où elle imprimera à quoi ressemblent les piles à chaque étape, alors ...
la source
System.out.println(Arrays.toString(s))
-il?&&
par&
.Python 2,
186167158 158135127115110 110102 octetsPrend entrée sur STDIN dans le format suivant:
Autrement dit, un tuple Python du nombre de disques et une liste Python de tuples de
(from_rod,to_rod)
. Comme en Python, les parenthèses environnantes sont facultatives. Les tiges sont indexées zéro.Par exemple, ce cas de test:
serait donné comme:
Si la solution est valide, ne produit rien et se termine avec un code de sortie de 0. Si elle n'est pas valide, lève une exception et se termine avec un code de sortie de 1. Lève un en
IndexError
cas de déplacement vers une tige inexistante ou en essayant de retirer un disque d'un tige sans disque, aZeroDivisionError
si un disque est placé sur un disque plus petit, ouNameError
s'il reste des disques sur la première ou la deuxième tige à la fin.13 octets enregistrés grâce à @KarlKastor!
8 octets enregistrés grâce à @xnor!
la source
Python 2.7,
173158138 138130127123 octets:Prend l'entrée via le stdin dans le format
(<Number of Discs>,<Moves>)
où<Moves>
est donné comme un tableau contenant des tuples correspondant à chaque mouvement, qui contiennent chacun une paire d'entiers séparés par des virgules. Par exemple, le cas de test:donné dans le poste serait donné comme:
à mon programme. Génère un
IndexError
si la 3e condition n'est pas remplie, aNameError
si la 2e condition n'est pas remplie etFalse
si la 1ère condition n'est pas remplie. Sinon, les sortiesTrue
.la source
Y
n'est jamais définie dans votre code (je pense que cela devrait être J) etU[J]+=[Y,[U[K].pop()]][U[J]<[1]or U[K]<U[J]]
est plus courte de 3 caractères que lestmt1 if cond else stmt2
Y
variable comme ça pour augmenter leNameError
chaque fois que la 2ème condition n'est pas remplie. Si je devais changerY
pourJ
, leNameError
ne serait pas levé. Pour cette raison, je ne peux pas non plus le faireU[J]+=[Y,[U[K].pop()]][U[J]<[1]or U[K]<U[J]]
car cela soulèveraitNameError
tout le temps , pas seulement lorsque la 2e condition n'est pas remplie.VBA,
234217213196 octetsLe format d'entrée pour les déplacements est une chaîne avec un nombre pair de chiffres (012). L'invocation est dans la feuille de calcul, = H ([nombre de disques], [chaîne de déplacement])
Le réseau A maintient la position de la tige des différents disques. Un mouvement met simplement à jour la première occurrence du numéro de tige "De" dans le numéro de tige "À". Si vous rencontrez d'abord un disque de tige «À», ou aucun disque de tige «De», c'est un mouvement invalide. La «valeur de tige» totale de A est maintenue en L, qui doit se terminer à 2N. Les erreurs sont accumulées sous forme de nombre négatif dans E.
Comme pour d'autres solutions, le «déplacement» d'un disque d'une tour vers la même tour n'est pas interdit. Je pourrais l'interdire pour 6 autres octets.
Résultats
Résultat de la fonction dans la première colonne (le dernier cas n = 3 est mon ajout à l'aide d'une tige supplémentaire).
la source
php, 141 octets
Script de ligne de commande, prend l'entrée comme hauteur puis une série d'index de tableau (indexés 0), par exemple 1 0 2 ou 2 0 1 0 2 1 2 pour les cas de test les plus courts de 1 ou 2 hauteurs.
Echos 1 sur les vrais cas et rien sur les faux.
Donne 2 avis et 1 avertissement, il doit donc être exécuté dans un environnement qui les réduit au silence.
la source
JavaScript (ES6), 108
Format d'entrée: fonction avec 2 arguments
Sortie: retourne 1 si ok, 0 si invalide, exception si tige inexistante
Moins golfé et expliqué
Test Note: la première ligne de la fonction Test est nécessaire pour convertir le format d'entrée donné dans la question en l'entrée attendue par ma fonction
la source