Merci à FryAmTheEggman pour l’inspiration nécessaire de la solution XOR.
0000 !@
0001 ?.|@!
0010 #?#!)@
0011 ?!@
0100 +?|@!?
0101 ??!@
0110 ?<@!!<_\~(
0111 ?<<@!
1000 )\!#?@{
1001 (~?/@#!
1010 ??|@!)
1011 \#??!1@
1100 ?(~!@
1101 ?.|@!)
1110 ?$@#)!<
1111 1!@
Tous les programmes utilisent 0
pour faux et 1
pour vrai.
Essayez-le en ligne! Ce n'est pas une suite de tests, vous devrez copier vous-même les différents programmes et entrées.
La solution ci-dessus se situe dans les 2 octets de l'optimalité (à moins que nous ne relâchions l'interprétation véracité / fausseté, je suppose). J'ai laissé un terme de recherche de force brute pour près de deux jours sur tous les programmes qui correspondent à côté de longueur 2, soit jusqu'à 7 octets (pas tout à fait tous les programmes - J'ai fait quelques hypothèses sur ce que tous les besoins du programme valides et ce qui ne programme valide aurait pu). La recherche a trouvé des solutions pour 15 des 16 portes possibles - et souvent bien plus qu’une seule. Vous pouvez trouver une liste de toutes les solutions alternatives dans cette pastebin où je les ai également regroupées par comportement équivalent. Celles que je présente ci-dessus ont été sélectionnées parce qu’elles représentent la solution la plus simple ou la plus intéressante, et j’en ajouterai des explications demain.
En ce qui concerne la 16e porte: XOR est la seule porte qui ne peut apparemment pas être mise en œuvre sur 7 octets. Une recherche par force brute sur des programmes plus importants n’est malheureusement pas réalisable avec le code que j’ai actuellement. Donc XOR devait être écrit à la main. Le plus court que j'ai trouvé jusqu'à présent est le programme de 10 octets ci-dessus, basé sur une tentative infructueuse (mais très proche) de FryAmTheEggman. Il est possible qu'une solution de 8 octets ou de 9 octets existe, mais à part cela, toutes les solutions devraient en effet être optimales.
Des explications
Attention: mur de texte. Heureusement, quiconque est intéressé par le fonctionnement de ces programmes hautement compressés d'Hexagony est présenté ci-dessous. J'ai essayé de choisir la solution la plus simple pour chaque porte dans les cas où il existe plusieurs programmes optimaux, afin de garder les explications assez courtes. Cependant, certains d'entre eux sont toujours aussi stupéfiants, alors j'ai pensé qu'ils méritaient un peu plus de précisions.
0000
: Faux
Je ne pense pas que nous aurons besoin d'un diagramme pour celui-ci:
! @
. . .
. .
Étant donné que toute la grille de mémoire est initialisée à !
zéro , affiche simplement un zéro et @
termine le programme.
C'est aussi la seule solution à 2 octets.
0001
: Et
? .
| @ !
. .
Cela met essentiellement en œuvre le court-circuit . Le diagramme gris ci-dessous montre le début du programme, où la première entrée est lue ?
et où le pointeur d'instruction (IP) se positionne dans le coin gauche où le |
miroir le reflète. Maintenant, le coin agit comme une condition, de sorte qu'il existe deux chemins d'exécution différents en fonction de la valeur de la première entrée. Le diagramme rouge montre le flux de contrôle pour A = 0
et le diagramme vert pour A = 1
:
Comme vous pouvez le constater, lorsque le fichier A
est 0
affiché, nous l’imprimons et l’arrêtons (rappelez-vous que tous .
ne sont pas opérationnels). Mais quand A
est 1
, alors l'IP traverse à nouveau la première ligne, en le lisant B
et en l'imprimant.
Au total, il existe seize solutions de 5 octets pour cette porte. Quatorze d' entre eux sont essentiellement les mêmes que ci - dessus, soit en utilisant à la >
place de |
ou en remplaçant l' .
aide d' une commande qui est en fait une no-op, ou la mise ?
dans la seconde position:
?.|@! .?|@! ?=|@! =?|@! ?_|@! _?|@! ?0|@!
?.>@! .?>@! ?=>@! =?>@! ?_>@! _?>@! ?0>@!
Et puis il y a deux autres solutions (qui sont équivalentes). Ceux-ci implémentent également la même logique de court-circuit, mais les chemins d'exécution sont un peu plus fous (et laissés comme exercice au lecteur):
?<!@|
?<!@<
0010
: A et non B
# ?
# ! )
@ .
Cela met également en œuvre une forme de court-circuit, mais en raison de l'utilisation du #
flux de contrôle est beaucoup plus délicat. #
est un commutateur IP conditionnel. Hexagony est en fait livré avec six adresses IP étiquetées 0
to 5
, qui commencent aux six coins de la grille et pointent dans le sens des aiguilles d'une montre (et le programme commence toujours par IP 0
). Lorsque a #
est rencontré, la valeur actuelle est prise modulo 6
et le flux de contrôle se poursuit avec l'adresse IP correspondante. Je ne suis pas sûr de savoir quelle folie m'a fait ajouter cette fonctionnalité, mais cela permet certainement de créer des programmes surprenants (comme celui-ci).
Nous distinguerons trois cas. Quand A = 0
, le programme est assez simple, car la valeur est toujours 0
quand #
est rencontrée, de sorte qu'aucune commutation IP n'a lieu:
#
ne fait rien, ?
lit A
(c'est-à-dire ne fait rien non plus), #
ne fait toujours rien, !
affiche le 0
, l' )
incrémente (c'est important, sinon l'adresse IP ne passerait pas à la troisième ligne), @
termine le programme. Assez simple. Considérons maintenant le cas (A, B) = (1, 0)
:
Le chemin rouge correspond toujours à IP 0
et j'ai ajouté le chemin vert pour IP 1
. Nous voyons qu'après les ?
lectures A
( 1
cette fois), les #
basculements vers l'IP qui commence dans le coin supérieur droit. Cela signifie ?
peut lire B
( 0
). )
Incrémente maintenant cela 1
, de sorte que le #
coin supérieur gauche ne fait rien et nous restons avec IP 1
. Les !
empreintes 1
et l'adresse IP s'enroule autour de la diagonale gauche. #
ne fait toujours rien et @
termine le programme.
Enfin, le cas vraiment étrange où les deux entrées sont 1
:
Cette fois -ci , la deuxième entrée est également 1
et )
incrémente à 2
. Cela signifie que #
dans le coin supérieur gauche, un autre commutateur IP est basculé sur IP 2
, indiqué en bleu. Sur cette trajectoire, nous incrémentons d’abord 3
(bien que ce ne soit pas pertinent) et passons ensuite ?
une troisième fois. Depuis que nous avons appuyé sur EOF (c’est-à-dire que l’entrée est épuisée), nous ?
retournons 0
, !
imprimons cela et @
terminons le programme.
C'est notamment la seule solution à 6 octets pour cette porte.
0011
: UNE
? !
@ . .
. .
C’est assez simple pour ne pas avoir besoin d’un diagramme: ?
lit A
, l’ !
imprime, se @
termine.
C'est la seule solution à 3 octets pour cette porte. (En principe, il serait également possible de le faire ,;@
, mais la recherche n'incluait pas ;
, car je ne pense pas qu'elle puisse jamais économiser des octets !
pour cette tâche.)
0100
: B et non A
+ ?
| @ !
? .
Celui-ci est beaucoup plus simple que son "frère" 0010
. Le flux de contrôle est en fait le même que nous avons vu ci-dessus pour 0001
(Et). Si A = 0
, alors l'IP traverse la ligne inférieure, en le lisant B
et en l'imprimant avant de se terminer. Si A = 1
ensuite, l'IP traverse à nouveau la première ligne, en lisant également B
, mais +
ajoute deux bords de mémoire inutilisés et réinitialise la valeur actuelle 0
pour qu'il !
imprime toujours 0
.
Il existe de nombreuses alternatives à 6 octets (42 au total). Premièrement, il existe une tonne de solutions équivalentes à ce qui précède. Nous pouvons à nouveau choisir librement entre |
et >
, et +
peuvent être remplacés par toute autre commande qui nous donne un bord vide:
"?|@!? &?|@!? '?|@!? *?|@!? +?|@!? -?|@!? ^?|@!? {?|@!? }?|@!?
"?>@!? &?>@!? '?>@!? *?>@!? +?>@!? -?>@!? ^?>@!? {?>@!? }?>@!?
En outre, nous pouvons également utiliser à la ]
place de ?
. ]
passe à l'adresse IP suivante (c.-à-d. sélectionne l'adresse IP 1
), de sorte que cette branche réutilise le ?
dans le coin supérieur droit. Cela donne 18 autres solutions:
"?|@!] &?|@!] '?|@!] *?|@!] +?|@!] -?|@!] ^?|@!] {?|@!] }?|@!]
"?>@!] &?>@!] '?>@!] *?>@!] +?>@!] -?>@!] ^?>@!] {?>@!] }?>@!]
Et puis il y a six autres solutions qui fonctionnent toutes différemment avec différents niveaux de folie:
/[<@!? ?(#!@] ?(#>@! ?/@#/! [<<@!? [@$\!?
0101
: B
? ?
! @ .
. .
Woohoo, un autre simple: lire A
, lire B
, imprimer B
, terminer. Il existe cependant des alternatives à cela. Comme il A
n’ya qu’un seul caractère, on peut aussi le lire avec ,
:
,?!@
Et il y a aussi la possibilité d'utiliser un simple ?
et d'utiliser un miroir pour le parcourir deux fois:
?|@! ?>@!
0110
: Xor
? < @
! ! < _
\ ~ ( . .
. . . .
. . .
Comme je l’ai dit plus haut, c’était la seule porte qui ne tienne pas dans side-length 2, c’est donc une solution manuscrite de FryAmTheEggman et moi-même, et il ya de fortes chances que ce ne soit pas optimal. Il y a deux cas à distinguer. Si A = 0
le flux de contrôle est assez simple (car dans ce cas, il suffit d'imprimer B
):
Nous commençons sur le chemin rouge. ?
lit A
, <
est une branche qui dévie le zéro à gauche. L'adresse IP est renvoyée vers le bas, puis se _
trouve un autre miroir. Lorsque l'adresse IP frappe le coin, elle s'affiche dans le coin supérieur gauche et continue sur le chemin bleu. ?
lit B
, !
imprime. Maintenant le (
décrémente. Ceci est important car il garantit que la valeur est non-positive (il est soit 0
ou -1
maintenant). Cela fait en sorte que IP se @
termine dans le coin droit, où se termine le programme.
Quand les A = 1
choses deviennent un peu plus compliquées. Dans ce cas, nous voulons imprimer not B
, ce qui en soi n’est pas trop difficile, mais le chemin d’exécution est un peu lent.
Cette fois, l' <
adresse IP est déviée à droite et ensuite, elle <
agit simplement comme un miroir. Donc, l'IP traverse le même chemin en sens inverse, en lisant B
quand il rencontre à ?
nouveau. L'adresse IP s'enroule dans le coin droit et continue sur le chemin vert. À côté des rencontres (~
qui est « décrémentation, multiplier par -1 », qui échanges 0
et 1
et calcule donc not B
. \
est juste un miroir et !
imprime le résultat souhaité. Puis ?
essaie de renvoyer un autre nombre mais renvoie zéro. L'adresse IP continue maintenant dans le coin inférieur gauche du chemin bleu. (
décroît, <
reflète,(
décrémente à nouveau, de sorte que la valeur actuelle est négative lorsque l’IP frappe le coin. Il se déplace à travers la diagonale en bas à droite puis frappe @
pour mettre fin au programme.
0111
: Ou
? <
< @ !
. .
Plus de court-circuit.
Le A = 0
cas (le chemin rouge) est un peu déroutant ici. L'adresse IP est déviée à gauche, se place dans le coin inférieur gauche, est immédiatement reflétée par <
et retourne ?
à lire B
. Il passe ensuite au coin droit, imprime B
avec !
et se termine.
Le A = 1
cas (le chemin vert) est un peu plus simple. La <
branche dévie l’adresse IP vers la droite; nous l’imprimons donc simplement, nous !
revenons en haut à gauche et nous terminons à @
.
Il n'y a qu'une seule autre solution à 5 octets:
\>?@!
Cela fonctionne essentiellement de la même manière, mais les chemins d’exécution réels sont très différents et il utilise un angle pour créer des branches au lieu d’un <
.
1000
: Ni
) \
! # ?
@ {
Ceci pourrait être mon programme préféré trouvé dans cette recherche. Le plus cool, c’est que cette implémentation nor
fonctionne réellement pour 5 entrées maximum. Je vais devoir entrer un peu dans les détails du modèle de mémoire pour expliquer celui-ci. En guise de mise à jour rapide, le modèle de mémoire de Hexagony est une grille hexagonale distincte, où chaque arête contient une valeur entière (initialement tout à zéro). Il existe un pointeur de mémoire (MP) qui indique un bord et une direction le long de ce bord (de telle sorte qu'il existe deux bords voisins devant et derrière le bord actuel, avec des voisins significatifs à gauche et à droite). Voici un diagramme des arêtes que nous allons utiliser, avec le MP démarrant comme indiqué en rouge:
Considérons d’abord le cas où les deux entrées sont 0
:
Nous commençons par le chemin gris, qui incrémente simplement le bord A de 1
manière à ce que les #
commutateurs passent à IP, 1
le chemin bleu, en partant du coin supérieur droit. \
ne fait rien et ?
lit une entrée. Nous allons au coin supérieur gauche où )
incrémente cette entrée. Maintenant, tant que l'entrée est à zéro, cela donnera un 1
, donc cela #
ne fait rien. Ensuite , {
déplace le MP vers la gauche, soit à la première itération de A à B . Comme ce bord a toujours son zéro initial, l’IP se replie dans le coin supérieur droit et sur un nouveau bord de mémoire. Donc, cette boucle continuera tant que ?
lira des zéros, déplaçant le PM autour de l'hexagone de Bà C à D et ainsi de suite. Peu importe si ?
retourne un zéro parce que c'était une entrée ou parce que c'était EOF.
Après six itérations à travers cette boucle, {
retourne à A . Cette fois-ci, l’arête contient déjà la valeur 1
de la toute première itération, de sorte que l’IP s’enroule dans le coin gauche et continue sur le chemin vert. !
imprime simplement cela 1
et @
termine le programme.
Maintenant, que se passe-t-il si l'une des entrées est 1
?
Puis ?
lit cela 1
à un moment donné et l’ )
incrémente 2
. Cela signifie #
que nous allons à nouveau changer d'adresse IP et continuer dans le coin droit du chemin rouge. ?
lit une autre entrée (s'il y en a une), ce qui importe peu et {
déplace un bord plus loin. Cela doit être un bord inutilisé, donc cela fonctionne pour 5 entrées maximum. L'adresse IP se situe en haut à droite, là où elle est immédiatement reflétée et dans le coin gauche. !
imprime le 0
sur le bord inutilisé et #
repasse sur IP 0
. Cette adresse IP attendait toujours sur le #
sud-ouest (chemin gris), elle frappe donc immédiatement @
et met fin au programme.
Au total, il existe sept solutions de 7 octets pour cette porte. 5 d'entre eux fonctionnent de la même manière et utilisent simplement d'autres commandes pour accéder à un bord non utilisé (et peuvent contourner un autre hexagone ou dans une direction différente):
)\!#?@" )\!#?@' )\!#?@^ )\!#?@{ )\!#?@}
Et il existe une autre classe de solutions qui ne fonctionne qu'avec deux entrées, mais dont les chemins d'exécution sont encore plus compliqués:
?]!|<)@ ?]!|<1@
1001
: Égalité
( ~
? / @
# !
Cela fait également une utilisation très intelligente de la sélection IP conditionnelle. Nous devons encore distinguer entre A = 0
et A = 1
. Dans le premier cas, nous voulons imprimer not B
, dans le second, nous voulons imprimer B
. Car A = 0
on distingue aussi les deux cas pour B
. Commençons par A = B = 0
:
Nous commençons sur le chemin gris. (~
peut être ignoré, l’IP se cache dans le coin gauche (toujours sur le chemin gris) et lit A
avec ?
. (
décrémente cela, donc nous obtenons -1
et IP Wrap dans le coin inférieur gauche. Maintenant, comme je l'ai dit plus tôt, #
prend la valeur modulo 6
avant de choisir l'adresse IP, donc une valeur correspondant -1
à l'IP réellement en sortie 5
, qui commence dans le coin gauche du chemin rouge. ?
lit B
, (
décrémente cela aussi afin que nous restions sur IP 5
lorsque nous frappons à #
nouveau. ~
nie le -1
pour que l'adresse IP soit renvoyée dans le coin inférieur droit, imprime le 1
et se termine.
Maintenant, si B
est 1
au lieu de cela, la valeur actuelle sera 0
lorsque nous frappons #
la deuxième fois, donc nous revenons à IP 0
(maintenant sur le chemin vert). Cela frappe ?
une troisième fois, cédant 0
, l’ !
imprimant et se @
terminant.
Enfin, le cas où A = 1
. Cette fois, la valeur actuelle est déjà égale à zéro lorsque nous frappons #
pour la première fois. Cela ne bascule donc jamais vers IP 5
. Nous continuons simplement immédiatement sur la voie verte. ?
maintenant ne donne pas simplement un zéro mais retourne à la B
place. !
l'imprime et se @
termine à nouveau.
Au total, il existe trois solutions de 7 octets pour cette porte. Les deux autres fonctionnent très différemment (même l'un par rapport à l'autre) et en font un usage encore plus bizarre #
. En particulier, ils lisent une ou plusieurs valeurs avec ,
(lire un code de caractère au lieu d'un entier), puis utilisent cette valeur modulo 6 pour choisir une adresse IP. C'est assez fou.
),)#?@!
?~#,~!@
1010
: Pas B
? ?
| @ !
) .
Celui-ci est assez simple. Le chemin d'exécution est la branche horizontale que nous connaissons déjà and
. ??
lit A
et puis immédiatement B
. Après avoir réfléchi sur at |
et branching, B = 0
nous allons exécuter la branche inférieure, où )
incrémente la valeur sur 1
laquelle est ensuite imprimée !
. Sur la branche supérieure (si B = 1
), ?
réinitialisez simplement le bord sur 0
lequel est également imprimé !
.
Il existe huit programmes de 6 octets pour cette porte. Quatre d'entre eux sont à peu près les mêmes, en utilisant soit >
au lieu de |
soit à la 1
place de )
(ou les deux):
??>@!) ??>@!1 ??|@!) ??|@!1
Deux utilisent un simple ?
qui est utilisé deux fois en raison d'un miroir. La négation se passe alors comme nous l’avons fait xor
avec (~
ou ~)
.
?>!)~@ ?>!~(@
Et enfin, deux solutions utilisent un commutateur IP conditionnel, car pourquoi utiliser la méthode simple si celle qui convient fonctionne également:
??#)!@ ??#1!@
1011
: B implique A
\ #
? ? !
1 @
Ceci utilise une commutation IP plutôt élaborée. Je vais commencer par le A = 1
cas cette fois, parce que c'est plus simple:
Nous commençons par le chemin gris qui lit A
avec ?
puis frappe sur le #
. Depuis A
est 1
cette bascule vers IP 1
(voie verte). Les !
impressions immédiates qui, l'adresse IP se cache en haut à gauche, lit B
(inutilement) et se termine.
Quand les A = 0
choses deviennent un peu plus intéressantes. D'abord, considérons A = B = 0
:
Cette fois, le #
ne fait rien et nous restons sur IP 0
(chemin rouge à partir de ce point). ?
lit B
et le 1
transforme en 1
. Après avoir terminé dans le coin en haut à gauche, nous avons #
encore frappé , nous finissons donc sur le chemin vert et imprimons 1
comme avant, avant de terminer.
Enfin, voici (A, B) = (0, 1)
le faux cas:
Notez que j'ai supprimé le chemin gris initial pour plus de clarté, mais le programme commence de la même manière et nous nous retrouvons sur le chemin rouge comme avant. Alors cette fois la seconde ?
revient 1
. Maintenant nous rencontrons le 1
. À ce stade, il est important de comprendre ce que les chiffres font réellement dans Hexagony (jusqu'à présent, nous ne les avons utilisés que sur des zéros): lorsqu'un chiffre est rencontré, la valeur actuelle est multipliée par 10, puis le chiffre est ajouté. Ceci est normalement utilisé pour écrire des nombres décimaux textuellement dans le code source, mais cela signifie qu’il B = 1
est mappé à la valeur 11
. Donc, lorsque nous frappons #
, cela est pris modulo 6
à donner 5
et donc nous passons à IP 5
(au lieu de 1
comme auparavant) et continuons sur le chemin bleu. Frappe?
une troisième fois renvoie un zéro, ainsi !
, après deux autres ?
, l'adresse IP est renvoyée en bas à droite, à l'endroit où le programme se termine.
Il existe quatre solutions à 7 octets à cela et elles fonctionnent toutes différemment:
#)/!?@$ <!?_@#1 \#??!1@ |/)#?@!
1100
: Pas un
? (
~ ! @
. .
Juste un simple linéaire: lire A
avec ?
, nier avec (~
, imprimer avec !
, terminer avec @
.
Il existe une solution alternative, et qui nie à la ~)
place:
?~)!@
1101
: A implique B
? .
| @ !
) .
C'est beaucoup plus simple que l'implication opposée dont nous venons de parler. C'est encore un de ces programmes de branche horizontaux, comme celui pour and
. Si A
c'est le cas 0
, il est simplement incrémenté 1
sur la branche inférieure et imprimé. Sinon, la branche supérieure est exécutée à nouveau, où elle est ?
lue B
, puis !
imprimée à la place.
Il y a une tonne d'alternatives ici (66 solutions au total), principalement en raison du libre choix de non-ops efficaces. Pour commencer, nous pouvons modifier la solution ci-dessus de la même manière que nous le pourrions and
et nous pouvons également choisir entre )
et 1
:
?.|@!) .?|@!) ?=|@!) =?|@!) ?_|@!) _?|@!) ?0|@!)
?.|@!1 .?|@!1 ?=|@!1 =?|@!1 ?_|@!1 _?|@!1 ?0|@!1
?.>@!) .?>@!) ?=>@!) =?>@!) ?_>@!) _?>@!) ?0>@!)
?.>@!1 .?>@!1 ?=>@!1 =?>@!1 ?_>@!1 _?>@!1 ?0>@!1
Et puis il y a une version différente utilisant la sélection IP conditionnelle, où la première commande peut être choisie presque arbitrairement, et il y a aussi un choix entre )
et 1
pour certaines de ces options:
"?#1!@ &?#1!@ '?#1!@ )?#1!@ *?#1!@ +?#1!@ -?#1!@ .?#1!@
0?#1!@ 1?#1!@ 2?#1!@ 3?#1!@ 4?#1!@ 5?#1!@ 6?#1!@ 7?#1!@
8?#1!@ 9?#1!@ =?#1!@ ^?#1!@ _?#1!@ {?#1!@ }?#1!@
"?#)!@ &?#)!@ '?#)!@ *?#)!@ +?#)!@ -?#)!@
0?#)!@ 2?#)!@ 4?#)!@ 6?#)!@
8?#)!@ ^?#)!@ _?#)!@ {?#)!@ }?#)!@
1110
: Nand
? $
@ # )
! <
Le dernier compliqué. Si vous lisez encore, vous avez presque fini. :) Regardons d' A = 0
abord:
?
lit A
et puis nous avons frappé $
. C'est une commande de saut (comme celle de Befunge #
) qui saute l'instruction suivante afin que nous ne terminions pas le @
. Au lieu de cela, l'IP continue à #
. Toutefois , depuis A
est - 0
, cela ne fait rien. )
l'incrémente 1
pour que l'adresse IP continue sur le chemin du bas où 1
est imprimé le. La <
dévie l'adresse IP vers la droite où il se termine dans le coin gauche et le programme se termine.
Ensuite, lorsque l'entrée est (A, B) = (1, 0)
nous obtenons cette situation:
Il est essentiellement le même que précédemment sauf que le #
nous allumons IP 1
(chemin vert), mais depuis B
est que 0
nous Revient IP 0
lorsque nous avons atteint #
une deuxième fois (chemin maintenant bleu), où il imprime 1
comme avant.
Enfin, le A = B = 1
cas:
Cette fois, lorsque nous #
la deuxième fois, la valeur actuelle est toujours 1
telle que nous ne modifions plus l’adresse IP. Le <
reflète et la troisième fois que nous frappons ?
nous obtenons un zéro. Par conséquent, l'adresse IP se cache en bas à gauche, où est !
imprimé le zéro et le programme se termine.
Il existe neuf solutions au total sur 7 octets pour cela. La première alternative utilise simplement 1
au lieu de )
:
?$@#1!<
Ensuite, deux solutions vous donneront le sens de la quantité de commutation IP en cours:
)?#_[!@ 1?#_[!@
C’est une idée intéressante: ce qui est intéressant, c’est que la commutation IP peut être utilisée comme condition conditionnelle différée. Les règles de commutation IP du langage sont telles que l'IP actuel effectue une étape supplémentaire avant que le commutateur ne se produise. Si cette étape passe par un coin, la valeur actuelle détermine la branche sur laquelle l’adresse IP se poursuivra si nous y revenions un jour. Cela se produit exactement lorsque l'entrée est A = B = 1
. Bien que tout cela soit cohérent avec la façon dont j'ai conçu la langue, je n’étais jamais conscient de cette implication de la spécification, c’est donc agréable que ma langue m’enseigne de nouvelles astuces: D.
Ensuite, il y a une troisième solution dont la quantité de commutation IP est encore pire (bien qu'elle n'utilise pas cet effet conditionnel différé):
>?1]#!@
Et puis il y en a un autre:
?$@#)!<
Et puis il y a ces quatre solutions équivalentes, qui utilisent une commutation IP non conditionnelle mais implémentent toute la logique via des branches et des coins:
]<?<@!) ]<?<@!1 ]|?<@!) ]|?<@!1
1111
: Vrai
1 !
@ . .
. .
Vous avez gagné quelque chose de simple pour la fin: régler le bord sur 1
, imprimer avec !
, terminer avec @
. :)
Bien sûr, il y a une alternative:
)!@
Comme d'habitude, tous les diagrammes de flux de contrôle créés avec HexagonyColorer de Timwi et le diagramme de mémoire avec EsotericIDE .