cinpush
main:
gte Hans 1s Leopold
jnz Leopold done
mov 1s Hans
gte Gertrude Hans Leopold
jnz Leopold done
mov Gertrude ShabbySam
mov Hans Gertrude
mov ShabbySam Hans
gte Alberto Gertrude Leopold
jnz Leopold done
mov Alberto ShabbySam
mov Gertrude Alberto
mov ShabbySam Gertrude
done:
mov 10 ShabbySam
gte 1s ShabbySam Leopold
jz Leopold undo_u
mov 30 ShabbySam
gte 1s ShabbySam Leopold
jz Leopold undo_d
undo_r:
POP!! 1
"shuffle" f
"shuffle" f
"shuffle" b
"shuffle" b
"shuffle" l
"shuffle" f
"shuffle" f
"shuffle" b
"shuffle" b
jmp end
undo_u:
POP!! 1
"shuffle" f
"shuffle" f
"shuffle" f
"shuffle" b
"shuffle" b
"shuffle" b
"shuffle" l
"shuffle" l
"shuffle" l
"shuffle" f
"shuffle" b
jmp end
undo_d:
POP!! 1
"shuffle" f
"shuffle" b
"shuffle" l
"shuffle" f
"shuffle" f
"shuffle" f
"shuffle" b
"shuffle" b
"shuffle" b
end:
jnz 1s main
print Hans
done!
C'était vraiment très amusant, merci Liam! :)
Merci à Sp3000 pour un léger mais nécessaire coup de pouce dans la bonne direction.
Comment?
Deux mots: Pocket Cube .
Il s'avère que les piles correspondent aux faces d'un cube Rubik 2x2x2 comme suit:
____ ____
| | |
| 19 | 17 |
|____U____|
| | |
| 20 | 18 |
_________|____|____|____ ____ ____ ____
| | | | | | | | |
| 13 | 14 | 1 | 2 | 9 | 10 | 6 | 5 |
|____L____|____F____|____R____|____B____|
| | | | | | | | |
| 15 | 16 | 3 | 4 | 11 | 12 | 8 | 7 |
|____|____|____|____|____|____|____|____|
| | |
| 22 | 24 |
|____D____|
| | |
| 21 | 23 |
|____|____|
Où ULFRBD
indiquer quelle face correspond à haut, gauche, avant, droite, arrière, bas lorsque le cube est correctement plié.
Les permutations correspondent à la rotation de n'importe quel côté de 90 degrés (où les noms correspondent heureusement). Il s'avère que f
, r
et d
sont des rotations dans le sens horaire (lors de la visualisation du visage) et r
, l
et u
sont des rotations dans le sens anti-horaire (lors de la visualisation du visage).
Maintenant, la cinpush
commande fonctionne de telle sorte qu'elle applique l'une des rotations u
, d
ou r
(en fonction de la valeur donnée), puis pousse la valeur d'entrée sur la pile en position 1
. (Et puis, il répète cette opération pour chaque élément de l'entrée.) Cela signifie que nous pouvons inverser ce processus (pour nous assurer que nous nous retrouvons avec le bon ordre de piles sans avoir à résoudre un cube Rubik arbitraire) en regardant à plusieurs reprises la pile dans position 1
, annulant la permutation correspondante et popping la valeur de cette pile (de sorte que la prochaine fois que nous voyons la pile, nous obtenons la valeur en dessous).
Comment annuler les rotations? Heureusement, nous avons les deux f
et b
à notre disposition. Si nous appliquons les deux, nous faisons pivoter le cube entier de 90 degrés. Cela signifie que nous pouvons déplacer le côté affecté ( U
, R
ou D
) vers L
, annuler la rotation en utilisant un ou trois l
s (selon la direction relative l
et la rotation effectuée lors de la saisie), puis faire pivoter le cube vers son orientation précédente à l'aide de f
et b
encore.
En particulier, chacune des rotations effectuées lors de la saisie peut être annulée comme suit:
u --> fffbbblllfb
r --> ffbblffbb
d --> fblfffbbb
Je vais voir si je peux proposer des animations pour montrer que cela fonctionne.
Maintenant, cela nous permet de parcourir une fois l'intégralité de l'entrée. Mais avec 5 registres, c'est tout ce dont nous avons besoin:
Alberto
est la valeur maximale rencontrée jusqu'à présent.
Gertrude
est la deuxième valeur la plus élevée rencontrée jusqu'à présent.
Hans
est la 3ème plus grande valeur rencontrée jusqu'à présent.
Lorsque nous rencontrons une nouvelle valeur, nous la remontons autant que nécessaire, où nous pouvons l'utiliser ShabbySam
comme registre temporaire pour les swaps. Cela laisse encore Leopold
que nous pouvons utiliser pour maintenir un conditionnel lors des comparaisons nécessaires.
À la fin du processus, nous imprimons simplement le contenu de Hans
, qui contiendra déjà la 3ème plus grande valeur.
TKDYNS par Sam Cappleman-Lynes
Ce n'est probablement pas optimal, mais je pense que ça fait l'affaire ...
Cela peut surprendre, mais je n'ai pas écrit cela à la main ... le code a été généré par le programme Mathematica suivant:
J'ai écrit toutes ces
safetyCheck
lignes à la main. Mais la première ligne de ce code Mathematica est en fait d'environ 28 000 caractères et a été elle-même générée par le code CJam suivant:(Ce qui prend en entrée les 10 dispositions codées en dur dans l'interpréteur. Vous pouvez exécuter le code en ligne. )
Génération de code-ception!
Explication
Pour commencer, jetez un œil à ce script CJam pour voir à quoi ressemblent les labyrinthes.
Ma solution est basée sur une observation importante: tant que nous récupérons des éléments le long d'une seule colonne, nous ne changerons pas de disposition, que les cellules soient remplies ou non. En particulier, tant que nous nous déplaçons le long de la colonne la plus à gauche, nous restons dans la disposition
0
. Tant que nous avancerons dans la colonne suivante, nous resterons dans la mise en page1
.La difficulté est de savoir comment nous assurer que nous avons changé entre les dispositions, car nous ne savons pas quelles cellules de la colonne
1
contiennent des éléments (le cas échéant!).Voici donc l'algorithme (à partir de la cellule
0
dans la disposition0
):Maintenant, pour chaque cellule à droite de la colonne actuelle (en les essayant dans l'ordre des colonnes), essayez de vous y déplacer dans la mise en page actuelle, ramassez-y un élément, puis passez à la ligne supérieure de cette nouvelle colonne en utilisant la nouvelle mise en page.
Si la cellule tentée contenait un élément, la disposition aura changé et nous atteindrons avec succès la nouvelle colonne et la nouvelle disposition. Étant donné que la nouvelle position (sûre) se trouve dans la ligne supérieure, mais que toutes les tentatives de recherche de la colonne suivante incluent 10 mouvements nets vers le haut, toutes les autres tentatives échoueront, nous pouvons donc les ignorer.
Si la cellule tentée ne contenait pas d'élément, dans la plupart des cas, le séide mourra lors de la tentative d'atteindre la ligne supérieure en utilisant la mauvaise disposition, rejetant ainsi cette tentative. Par contre, ce n'est pas toujours le cas. Par exemple, la cellule tentée peut déjà être sur la ligne supérieure, donc aucun déplacement n'a été effectué sur la nouvelle disposition. De même, dans certains cas, le chemin de la cellule tentée à la ligne supérieure est suffisamment court pour être valide sur les deux présentations. J'ai collecté tous les cas où c'est un problème à la main et déterminé un ensemble de mouvements qui n'est que valide la nouvelle mise en page (mais qui se déplace le dos sbire à la cellule cible, il est donc effectivement un non-op sur le nouvelle mise en page). Après chaque tentative où cela peut être un problème, j'effectue cet ensemble de mouvements pour tuer tous les serviteurs qui n'ont pas
Nous avons maintenant réussi à passer en haut de la colonne suivante qui contient au moins un élément. Revenez à l'étape 1.
Vous remarquerez peut-être que la structure de la solution est la suivante:
Quant au code Mathematica, les
safetyCheck
chaînes sont ces mouvements triés sur le volet qui garantissent que nous avons atteint la nouvelle disposition. Le premier paramètre de la recherche est la disposition à partir de laquelle nous partons et le second est la cellule que nous avons tentée. Toutes les combinaisons qui ne sont pas mentionnées explicitement donnent simplement un contrôle de sécurité vide (car aucune n'est nécessaire).En plus de cela, je configure simplement les 10 labyrinthes en tant
Graph
qu'objets, où il y a deux bords dirigés entre les cellules adjacentes (et connectées), où chaque bord est annoté avec le mouvement requis pour traverser le bord. Avec cela en place, je peux simplement trouver les chemins en utilisantFindShortestPath
puis extraire les étiquettes de bord correspondantes avecPropertyValue[..., EdgeLabels]
.Le reste du code utilise simplement cela pour implémenter l'algorithme ci-dessus assez directement.
Les données réelles du graphique sont stockées dans
layouts
et ont été générées avec le script CJam, qui décode les nombres comme décrit dans la publication de la police et les transforme en une liste Mathematica, qui peut facilement être transformée en graphique.la source
HPR, par Zgarb
Le code:
Tout d'abord ... le code a été généré, pas écrit à la main (ou tapé).
Faits sur la langue:
Le programme utilise le pseudo-code suivant:
L'environnement contient presque toujours seulement 1 liste et 1 entier.
Afin de résoudre ce problème, j'ai créé un petit moteur macro pour cette langue. Il permet également des commentaires. Voici le macro-moteur:
Après avoir construit le moteur de macro, j'ai lentement développé des fonctions utiles pour ce langage. Voici le code que le moteur a traité pour créer le programme:
la source
Brian & Chuck par Martin Büttner
Le programme Python 2.7 suivant génère mon programme Brian & Chuck, en traduisant un programme brainfuck en Brian & Chuck (à l'exception qui
.
s'imprime toujours1
, car c'est le seul caractère que nous devons produire).Le flux de contrôle fonctionne par
magie endemandant à Brian d'écrire sur les commandes de bande de Chuck pour envoyer Brian à la bonne position dans le code.Notez que les espaces et les
[]
s ajoutés au programme B&C sont uniquement décoratifs.la source
Firetype, par kirbyfan64sos
Code de travail, commenté:
Cela repose sur l'interprète tel qu'il est actuellement fourni dans la réponse du policier, ce qui contredit légèrement la documentation concernant
%
et!
.Le principal défi ici était d'analyser les données d'entrée, car cela
\
rend la recherche de la troisième plus grande valeur assez simple.la source
Acc !, par DLosc
Cette langue a un support de comparaison terrible .
Les
count [varname] while 0
instructions au début doivent déclarer la variable contenant le plus grand nombre, le deuxième plus grand nombre, le troisième plus grand nombre, etc. Les comparaisons sont effectuées en soustrayant les deux nombres puis en vérifiant si le résultat est négatif en vérifiant s'il s'agit d'un nombre inférieur à celui-ci10^6
.la source
Zinc, par kirbyfan64sos
Ce n'était pas si difficile, une fois que j'ai compris comment la langue fonctionne. La partie difficile était de contourner les erreurs de l'analyseur, mais l'ajout de parenthèses superflues semblait résoudre ce problème. Voici la solution:
Explication
Dans les première et deuxième lignes, je définis
+
comme étant l'cut
opération. Le reste est des compréhensions définies. Prenons l'exemple de l'entrée101011101100
et commençons par le plus intérieur:Cela prend ces éléments
a
de l'ensemble d'entréeS = {1,0,1,0,1,1,1,0,1,1,0,0}
dont l'indice n'est paslen(S)-1
, donc tous sauf le dernier. J'ai remarqué que cela inverse également l'ensemble, donc le résultat estA = {0,1,1,0,1,1,1,0,1,0,1}
. Ensuite, la compréhensionprend tous les éléments de l'
A
exception du premier et l'inverse à nouveau, résultant enB = {1,0,1,0,1,1,1,0,1,1}
. Ensuite, nous avons diviséB
au0
s (cela entraîne{1,1,{1,1,1},{1,1}}
ou son inversion, je n'ai pas vérifié lequel), et trions le résultat par longueur. Les ensembles singleton sont aplatis, mais ils sont tous1
s donc leur longueur est toujours de 1. Voici le code:Le résultat de ceci est
C = {{1,1,1},{1,1},1,1}
. Enfin, nous filtrons tout sauf l'élément à l'index 2 parIl en résulte l'ensemble
D = {1}
sur notre cas. En général, il peut avoir le formulaire{{1,1,..,1}}
, mais cela n'a pas d'importance car seuls les1
s sont imprimés.la source
Compass Soup, par BMac
C'était amusant.
Edit: ce programme doit être précédé d'une nouvelle ligne afin de travailler sur l'interprète de BMac. Je n'arrive pas à faire apparaître la nouvelle ligne dans le bloc de code.
Le programme est divisé en 4 sections d'exécution.
Le premier, à la ligne 1, ajoute un
#
à la fin de l'entrée en trouvant00
et en remplaçant le 2e0
par#
. Cela change également tous les1
s enA
s, car je voulais avoir le moins1
s possible dans le code source.La deuxième section, à la ligne 5, récupère le deuxième nombre dans l'entrée et le place sous le premier nombre sous la forme d'une chaîne de
+
s. Par exemple, si l'entrée est11011101100
, cela se traduira par ce qui suit:La troisième section, à la ligne 12, combine la chaîne de
+
s avec le premier nombre: chacun0
au-dessus de a+
devientA
,A
devientB
,B
devientC
etC
reste inchangé. Ensuite, nous revenons à la 2ème section pour récupérer le numéro suivant.Une fois que tous les nombres ont été combinés de cette façon, nous atteignons la dernière section à la ligne 18. Le nombre de
C
s est notre sortie souhaitée, nous les changeons donc en1
s, en sautant le premierC
car il y en a un1
dans le code source qui est imprimé le long avec la sortie.la source