Vielen Dank an FryAmTheEggman für die notwendige Inspiration für die XOR-Lösung.
0000 !@
0001 ?.|@!
0010 #?#!)@
0011 ?!@
0100 +?|@!?
0101 ??!@
0110 ?<@!!<_\~(
0111 ?<<@!
1000 )\!#?@{
1001 (~?/@#!
1010 ??|@!)
1011 \#??!1@
1100 ?(~!@
1101 ?.|@!)
1110 ?$@#)!<
1111 1!@
Alle Programme verwenden 0
für falsch und 1
für wahr.
Probieren Sie es online! Dies ist keine Testsuite, Sie müssen die verschiedenen Programme und Eingaben selbst kopieren.
Die obige Lösung liegt innerhalb von 2 Bytes der Optimalität (es sei denn, wir lockern die wahrheitsgemäße / falsche Interpretation, denke ich). Ich habe für eine enge über alle Programme bis zwei Tagen eine Brute - Force - Suche laufen lassen , die 2 in Seitenlänge passen, dh bis zu 7 Bytes (nicht ganz alle Programme - ich einige Annahmen darüber , was jeweils gültigen Programm Bedürfnisse gemacht und was nicht gültiges Programm haben könnte). Die Suche ergab Lösungen für 15 der 16 möglichen Tore - und oft viel mehr als nur eines. In diesem Pastebin finden Sie eine Liste aller alternativen Lösungen, die ich auch nach gleichem Verhalten gruppiert habe. Die oben gezeigten habe ich ausgewählt, weil sie entweder die einfachste oder die interessanteste Lösung sind, und ich werde morgen Erklärungen für sie hinzufügen.
Was das 16. Gatter betrifft: XOR ist das einzige Gatter, das anscheinend nicht in 7 Bytes implementiert werden kann. Eine Brute-Force-Suche über größere Programme ist mit dem Code, den ich derzeit habe, leider nicht möglich. Also musste XOR von Hand geschrieben werden. Das kürzeste, das ich bisher gefunden habe, ist das obige 10-Byte-Programm, das auf einem fehlgeschlagenen (aber sehr knappen) Versuch von FryAmTheEggman basiert. Es ist möglich, dass eine 8-Byte- oder 9-Byte-Lösung vorhanden ist, aber ansonsten sollten alle Lösungen in der Tat optimal sein.
Erklärungen
Warnung: Textwand. Falls Sie sich nicht dafür interessieren, wie diese hochkomprimierten Hexagony-Programme tatsächlich funktionieren, haben wir nachfolgend Erläuterungen zu den einzelnen Programmen aufgeführt. Ich habe versucht, für jedes Gatter die einfachste Lösung zu wählen, wenn mehr als ein optimales Programm existiert, um die Erklärungen einigermaßen kurz zu halten. Einige von ihnen verwirren jedoch immer noch den Verstand, weshalb ich der Meinung war, dass sie etwas mehr Ausarbeitung verdienen.
0000
: Falsch
Ich glaube nicht, dass wir dafür ein Diagramm brauchen:
! @
. . .
. .
Da das gesamte Speicherraster mit Nullen initialisiert ist, wird !
einfach eine Null ausgegeben und @
das Programm beendet.
Dies ist auch die einzige 2-Byte-Lösung.
0001
: Und
? .
| @ !
. .
Dies führt im Grunde genommen zu einem Kurzschluss . Das graue Diagramm unten zeigt den Beginn des Programms, bei dem die erste Eingabe gelesen wird ?
und der Anweisungszeiger (IP) in die linke Ecke übergeht, in der der |
Spiegel sie widerspiegelt. Jetzt fungiert die Ecke als Bedingung, sodass es je nach Wert der ersten Eingabe zwei verschiedene Ausführungspfade gibt. Das rote Diagramm zeigt den Kontrollfluss für A = 0
und das grüne Diagramm für A = 1
:
Wie Sie sehen können, wenn das A
ist 0
, dann drucken wir es einfach und beenden (denken Sie daran , dass alle .
No-ops sind). Wenn dies A
jedoch 1
der Fall ist, durchläuft die IP die erste Zeile erneut und liest B
und druckt diese stattdessen aus.
Insgesamt gibt es 16 5-Byte-Lösungen für dieses Gatter. Vierzehn davon sind im Wesentlichen die gleichen wie oben, entweder indem Sie >
anstelle von |
oder durch .
einen Befehl ersetzen , der praktisch ein No-Op ist, oder indem Sie ?
die zweite Position einnehmen:
?.|@! .?|@! ?=|@! =?|@! ?_|@! _?|@! ?0|@!
?.>@! .?>@! ?=>@! =?>@! ?_>@! _?>@! ?0>@!
Und dann gibt es zwei andere Lösungen (die einander äquivalent sind). Diese implementieren ebenfalls die gleiche Kurzschlusslogik, aber die Ausführungspfade sind etwas verrückter (und dem Leser als Übung überlassen):
?<!@|
?<!@<
0010
: A und nicht B
# ?
# ! )
@ .
Dies führt auch zu einer Art Kurzschluss, der jedoch aufgrund der Verwendung des #
Kontrollflusses viel schwieriger ist. #
ist ein bedingter IP-Switch. Hexagony wird mit sechs IPs mit der Bezeichnung 0
to geliefert 5
, die in den sechs Ecken des Rasters beginnen und entlang ihrer Kante im Uhrzeigersinn zeigen (und das Programm beginnt immer mit IP 0
). Wenn a #
angetroffen wird, wird der aktuelle Wert modulo genommen 6
und der Steuerungsfluss mit der entsprechenden IP fortgesetzt. Ich bin mir nicht sicher, welche Wahnsinnsanpassung mich veranlasst hat, diese Funktion hinzuzufügen, aber sie ermöglicht sicherlich einige überraschende Programme (wie dieses).
Wir werden drei Fälle unterscheiden. Wann A = 0
ist das Programm ziemlich einfach, weil der Wert immer 0
dann #
ist, wenn es auftritt, so dass keine IP-Umschaltung stattfindet:
#
tut nichts, ?
liest A
(dh tut auch nichts), #
tut immer noch nichts, !
druckt das 0
, )
inkrementiert es (das ist wichtig, sonst springt die IP nicht in die dritte Zeile), @
beendet das Programm. Einfach genug. Betrachten wir nun den Fall (A, B) = (1, 0)
:
Der rote Pfad entspricht immer noch IP 0
, und ich habe den grünen Pfad für IP hinzugefügt 1
. Wir sehen, dass nach dem ?
Lesen A
( 1
dieses Mal) #
auf die IP umgeschaltet wird, die in der oberen rechten Ecke beginnt. Das heißt ?
kann lesen B
( 0
). Nun )
inkrementiert das zu 1
, so dass die #
in der oberen linken Ecke nichts macht und wir bei IP bleiben 1
. Der !
Ausdruck 1
und die IP-Adresse werden um die linke Diagonale gewickelt. #
tut immer noch nichts und @
beendet das Programm.
Schließlich der wirklich seltsame Fall, in dem beide Eingaben sind 1
:
Diesmal ist auch der zweite Eingang 1
und )
erhöht ihn auf 2
. Das heißt, die #
in der oberen linken Ecke veranlasst einen weiteren IP-Switch auf IP 2
, blau anzuzeigen. Auf diesem Weg erhöhen wir ihn zuerst weiter 3
(obwohl das irrelevant ist) und übergeben ihn dann ?
ein drittes Mal. Da wir jetzt auf EOF geklickt haben (dh die Eingabe ist erschöpft), wird das ?
zurückgegeben 0
, !
gedruckt und @
das Programm beendet.
Dies ist insbesondere die einzige 6-Byte-Lösung für dieses Gate.
0011
: EIN
? !
@ . .
. .
Dies ist so einfach, dass wir kein Diagramm benötigen: ?
Liest A
, !
druckt und @
beendet es.
Dies ist die einzige 3-Byte-Lösung für dieses Gate. (Im Prinzip wäre es auch möglich ,;@
, aber die Suche schloss nicht ein ;
, da ich glaube, dass es !
für diese Aufgabe niemals Bytes einsparen kann .)
0100
: B und nicht A
+ ?
| @ !
? .
Dieser ist viel einfacher als sein "Bruder" 0010
. Der Kontrollfluss ist tatsächlich derselbe, den wir oben für 0001
(Und) gesehen haben. Wenn ja A = 0
, dann überquert die IP die untere Zeile und liest B
und druckt diese, bevor sie beendet wird. Wenn A = 1
dann die IP die erste Zeile erneut durchläuft und ebenfalls liest B
, werden jedoch +
zwei nicht verwendete Speicherflanken hinzugefügt, sodass nur der aktuelle Wert auf zurückgesetzt wird 0
, sodass !
immer gedruckt wird 0
.
Es gibt ziemlich viele 6-Byte-Alternativen dazu (insgesamt 42). Erstens gibt es eine Menge Lösungen, die den oben genannten entsprechen. Wir können wieder frei zwischen |
und wählen >
und +
können durch jeden anderen Befehl ersetzt werden, der uns eine leere Kante gibt:
"?|@!? &?|@!? '?|@!? *?|@!? +?|@!? -?|@!? ^?|@!? {?|@!? }?|@!?
"?>@!? &?>@!? '?>@!? *?>@!? +?>@!? -?>@!? ^?>@!? {?>@!? }?>@!?
Darüber hinaus können wir ]
stattdessen auch verwenden ?
. ]
wechselt zur nächsten IP (dh wählt IP aus 1
), so dass dieser Zweig stattdessen die ?
in der oberen rechten Ecke wiederverwendet . Das ergibt weitere 18 Lösungen:
"?|@!] &?|@!] '?|@!] *?|@!] +?|@!] -?|@!] ^?|@!] {?|@!] }?|@!]
"?>@!] &?>@!] '?>@!] *?>@!] +?>@!] -?>@!] ^?>@!] {?>@!] }?>@!]
Und dann gibt es noch sechs andere Lösungen, die alle unterschiedlich funktionieren und unterschiedlich verrückt sind:
/[<@!? ?(#!@] ?(#>@! ?/@#/! [<<@!? [@$\!?
0101
: B
? ?
! @ .
. .
Woohoo, ein anderes einfaches: lesen A
, lesen B
, drucken B
, beenden. Es gibt jedoch tatsächlich Alternativen dazu. Da A
es sich nur um ein einzelnes Zeichen handelt, können wir es auch lesen mit ,
:
,?!@
Es besteht auch die Möglichkeit, einen einzelnen ?
und einen Spiegel zu verwenden, um ihn zweimal zu durchlaufen:
?|@! ?>@!
0110
: Xor
? < @
! ! < _
\ ~ ( . .
. . . .
. . .
Wie ich oben sagte, war dies das einzige Tor, das nicht in Seitenlänge 2 passte, also eine handschriftliche Lösung von FryAmTheEggman und mir, und es besteht die gute Chance, dass es nicht optimal ist. Es sind zwei Fälle zu unterscheiden. Wenn A = 0
der Kontrollfluss ziemlich einfach ist (weil wir in diesem Fall nur drucken müssen B
):
Wir beginnen auf dem roten Weg. ?
liest A
, <
ist ein Zweig, der die Null nach links ablenkt. Die IP-Adresse wird nach unten umgebrochen und ist dann _
ein weiterer Spiegel. Wenn die IP-Adresse die Ecke erreicht, wird sie nach links oben umgebrochen und auf dem blauen Pfad fortgesetzt. ?
liest B
, !
druckt es. Jetzt (
dekrementiert es. Dies ist wichtig, da sichergestellt wird, dass der Wert nicht positiv ist (entweder 0
oder -1
jetzt). Das macht IP-Wrap in die rechte Ecke, wo @
das Programm beendet wird.
Wenn A = 1
es etwas kniffliger wird. In diesem Fall möchten wir drucken not B
, was an sich nicht allzu schwierig ist, aber der Ausführungspfad ist etwas trippelig.
Diesmal <
lenkt der die IP rechts ab und fungiert dann <
nur noch als Spiegel. Die IP durchläuft also denselben Pfad in umgekehrter Reihenfolge und liest, B
wenn sie ?
erneut auf sie trifft . Die IP wickelt sich in der rechten Ecke um und fährt auf dem grünen Pfad fort. Als nächstes (~
wird festgestellt, was "Dekrement, Multiplikation mit -1" ist, was tauscht 0
und 1
und daher berechnet not B
. \
ist nur ein Spiegel und !
druckt das gewünschte Ergebnis. Dann ?
versucht eine andere Nummer zurück , sondern gibt Null zurück. Die IP wird nun in der unteren linken Ecke des blauen Pfads fortgesetzt. (
dekrementiert, <
reflektiert,(
verringert sich erneut, so dass der aktuelle Wert negativ ist, wenn die IP die Ecke trifft. Es bewegt sich über die untere rechte Diagonale und trifft schließlich, @
um das Programm zu beenden.
0111
: Oder
? <
< @ !
. .
Mehr Kurzschluss.
Der A = 0
Fall (der rote Pfad) ist hier etwas verwirrend. Die IP wird nach links abgelenkt, in die untere linke Ecke umbrochen, wird sofort von der reflektiert <
und kehrt zum ?
zu lesenden zurück B
. Es wickelt dann an die großen rechten Ecke, druckt B
mit !
und beendet.
Der A = 1
Fall (der grüne Weg) ist etwas einfacher. Der <
Zweig lenkt die IP nach rechts um, also drucken wir sie einfach aus !
, brechen nach links oben zurück und enden bei @
.
Es gibt nur eine andere 5-Byte-Lösung:
\>?@!
Es funktioniert im Wesentlichen gleich, aber die tatsächlichen Ausführungspfade sind sehr unterschiedlich und es wird eine Ecke zum Verzweigen anstelle von a verwendet <
.
1000
: Noch
) \
! # ?
@ {
Dies könnte mein Lieblingsprogramm sein, das in dieser Suche gefunden wurde. Das Coolste ist, dass diese Implementierung nor
tatsächlich für bis zu 5 Eingänge funktioniert. Ich muss ein wenig auf die Details des Speichermodells eingehen, um dieses zu erklären. Zur schnellen Auffrischung ist das Speichermodell von Hexagony ein separates hexagonales Gitter, in dem jede Kante einen ganzzahligen Wert enthält (anfangs alle Nullen). Es gibt einen Speicherzeiger (MP), der eine Kante und eine Richtung entlang dieser Kante angibt (so dass sich zwei benachbarte Kanten vor und hinter der aktuellen Kante befinden, mit sinnvollen linken und rechten Nachbarn). Hier ist ein Diagramm der Kanten, die wir verwenden werden, wobei der MP wie in Rot angezeigt beginnt:
Betrachten wir zunächst den Fall, in dem beide Eingaben wie folgt lauten 0
:
Wir beginnen auf dem grauen Pfad, der einfach die Kante A inkrementiert , 1
so dass der #
IP- 1
Pfad, der der blaue Pfad ist, in der rechten oberen Ecke beginnt. \
tut dort nichts und ?
liest eine Eingabe. Wir springen in die linke obere Ecke, wo )
diese Eingabe erhöht wird. Solange die Eingabe null ist, führt dies zu a 1
, sodass #
nichts unternommen wird. Dann {
bewegt sich der MP auf der linken Seite, also auf der ersten Iteration von A zu B . Da diese Kante noch ihre anfängliche Null hat, springt die IP zurück in die obere rechte Ecke und auf eine neue Speicherkante. Diese Schleife wird also so lange fortgesetzt, wie ?
Nullen gelesen werden und der MP von B um das Sechseck verschoben wirdzu C zu D und so weiter. Es spielt keine Rolle, ob ?
eine Null zurückgegeben wird, weil es sich um eine Eingabe oder um eine EOF handelt.
Kehrt nach sechs Iterationen durch diese Schleife {
zu A zurück . Diesmal enthält die Kante bereits den Wert 1
der ersten Iteration, sodass die IP in die linke Ecke übergeht und stattdessen auf dem grünen Pfad fortgesetzt wird. !
druckt es einfach aus 1
und @
beendet das Programm.
Was ist nun, wenn einer der Eingänge ist 1
?
Dann ?
liest man das 1
irgendwann und )
erhöht es auf 2
. Das heißt #
, jetzt werden die IPs wieder gewechselt und wir fahren in der rechten Ecke auf dem roten Pfad fort. ?
Liest eine andere Eingabe (falls vorhanden), die keine Rolle spielt, und {
verschiebt eine Kante weiter. Dies muss eine nicht verwendete Flanke sein, daher funktioniert dies für bis zu 5 Eingänge. Die IP-Adresse wird rechts oben umbrochen, wo sie sofort wiedergegeben wird, und in der linken Ecke. !
druckt die 0
auf der unbenutzten Kante und #
wechselt zurück zu IP 0
. Diese IP wartete noch auf dem #
nach Südwesten gehenden (grauen Pfad), sodass sie sofort die trifft @
und das Programm beendet.
Insgesamt gibt es sieben 7-Byte-Lösungen für dieses Gate. 5 von ihnen funktionieren genauso und verwenden einfach andere Befehle, um zu einer nicht verwendeten Kante zu gelangen (und können um ein anderes Sechseck oder in eine andere Richtung laufen):
)\!#?@" )\!#?@' )\!#?@^ )\!#?@{ )\!#?@}
Und es gibt noch eine andere Lösungsklasse, die nur mit zwei Eingängen funktioniert, deren Ausführungspfade jedoch noch unübersichtlicher sind:
?]!|<)@ ?]!|<1@
1001
: Gleichberechtigung
( ~
? / @
# !
Dies nutzt auch die bedingte IP-Auswahl sehr geschickt aus. Wir müssen wieder zwischen A = 0
und unterscheiden A = 1
. Im ersten Fall möchten wir drucken not B
, im zweiten möchten wir drucken B
. Denn A = 0
wir unterscheiden auch die beiden Fälle für B
. Beginnen wir mit A = B = 0
:
Wir beginnen auf dem grauen Weg. (~
ignoriert werden kann, bricht die IP in die linke Ecke (immer noch auf dem grauen Pfad) und liest A
mit ?
. (
dekrementiert das, so dass wir bekommen -1
und IP in die untere linke Ecke umbrechen. Nun, wie ich bereits sagte, #
nimmt der Wert Modulo 6
vor der Auswahl der IP, so dass ein Wert von -1
IP tatsächlich rauskommt 5
, der in der linken Ecke auf dem roten Pfad beginnt. ?
liest B
, (
dekrementiert das auch so, dass wir auf IP bleiben, 5
wenn wir #
erneut schlagen . ~
negiert das, -1
so dass die IP in die untere rechte Ecke umbrochen wird, druckt das 1
und endet.
Wenn dies stattdessen der Fall B
ist 1
, wird der aktuelle Wert 0
beim #
zweiten Mal angezeigt, sodass wir wieder zu IP wechseln 0
(jetzt auf dem grünen Pfad). Das trifft ?
ein drittes Mal, gibt nach 0
, !
druckt es aus und @
endet.
Schließlich der Fall, wo A = 1
. Diesmal ist der aktuelle Wert bereits Null, wenn wir #
zum ersten Mal drücken, daher wechselt dieser Wert nie 5
in erster Linie auf IP . Wir fahren einfach sofort auf dem grünen Weg weiter. ?
Jetzt gibt es nicht nur eine Null, sondern kehrt B
stattdessen zurück. !
druckt es aus und @
bricht es erneut ab.
Insgesamt gibt es drei 7-Byte-Lösungen für dieses Gate. Die beiden anderen arbeiten sehr unterschiedlich (sogar voneinander) und machen noch seltsamer Gebrauch davon #
. Insbesondere lesen sie einen oder mehrere Werte mit ,
(Lesen eines Zeichencodes anstelle einer ganzen Zahl) und verwenden dann diesen Wert modulo 6, um eine IP auszuwählen. Es ist ziemlich verrückt.
),)#?@!
?~#,~!@
1010
: Nicht B
? ?
| @ !
) .
Dieser ist ziemlich einfach. Der Ausführungspfad ist der horizontale Zweig, den wir bereits and
früher kennen. ??
liest A
und dann sofort B
. Nachdem wir überlegt |
und verzweigt haben, werden B = 0
wir den untersten Zweig ausführen, in dem )
der Wert erhöht wird, um den 1
dann gedruckt wird !
. Auf dem oberen Ast (wenn B = 1
) wird ?
einfach die Kante zurückgesetzt, auf 0
die dann auch durch gedruckt wird !
.
Es gibt acht 6-Byte-Programme für dieses Gatter. Vier davon sind ziemlich gleich und verwenden entweder >
statt |
oder 1
statt )
(oder beides):
??>@!) ??>@!1 ??|@!) ??|@!1
Zwei verwenden ein einzelnes, ?
das aufgrund eines Spiegels zweimal verwendet wird. Die Verneinung geschieht dann wie xor
bei entweder (~
oder ~)
.
?>!)~@ ?>!~(@
Und schließlich verwenden zwei Lösungen einen bedingten IP-Switch, denn warum auf einfache Weise, wenn der gewundene auch funktioniert:
??#)!@ ??#1!@
1011
: B impliziert A
\ #
? ? !
1 @
Hierfür wird ein ziemlich aufwändiges IP-Switching verwendet. Ich werde A = 1
dieses Mal mit dem Fall beginnen, weil es einfacher ist:
Wir beginnen auf dem grauen Pfad, der liest A
mit ?
und trifft dann auf die #
. Da A
ist 1
diese IP - Schalter 1
(grüner Pfad). Der !
druckt sofort das, die IP bricht nach links oben ab, liest B
(unnötig) und bricht ab.
Wenn A = 0
es ein bisschen interessanter wird. Betrachten wir zuerst A = B = 0
:
Diesmal #
macht der nichts und wir bleiben auf IP 0
(roter Pfad von diesem Punkt an). ?
liest B
und 1
verwandelt es in eine 1
. Nachdem wir in die obere linke Ecke gewickelt haben, schlagen wir #
erneut zu, sodass wir schließlich auf dem grünen Pfad landen und 1
vor dem Beenden wie zuvor drucken .
Schließlich ist hier (A, B) = (0, 1)
der falsche Fall:
Beachten Sie, dass ich den anfänglichen grauen Pfad aus Gründen der Übersichtlichkeit entfernt habe, das Programm jedoch auf die gleiche Weise beginnt und wir wie zuvor auf dem roten Pfad landen. Diesmal ?
kehrt die Sekunde zurück 1
. Jetzt begegnen wir dem 1
. An dieser Stelle ist es wichtig zu verstehen, was Ziffern in Hexagony tatsächlich tun (bisher haben wir sie nur für Nullen verwendet): Wenn eine Ziffer angetroffen wird, wird der aktuelle Wert mit 10 multipliziert und dann die Ziffer hinzugefügt. Dies wird normalerweise verwendet, um Dezimalzahlen wörtlich in den Quellcode zu schreiben. Dies bedeutet jedoch, dass diese B = 1
tatsächlich dem Wert zugeordnet sind 11
. Wenn wir also drücken #
, wird dies als Modulo genommen 6
, 5
und daher wechseln wir zu IP 5
(anstatt 1
wie zuvor) und fahren auf dem blauen Pfad fort. Schlagen?
Ein drittes Mal gibt eine Null zurück, also wird diese !
ausgegeben, und nach zwei weiteren ?
wird die IP rechts unten umgebrochen, wo das Programm endet.
Hierfür gibt es vier 7-Byte-Lösungen, die alle unterschiedlich funktionieren:
#)/!?@$ <!?_@#1 \#??!1@ |/)#?@!
1100
: Kein
? (
~ ! @
. .
Nur eine einfache lineare: Lesen A
mit ?
, Negieren mit (~
, Drucken mit !
, Beenden mit @
.
Es gibt eine alternative Lösung, und die negiert ~)
stattdessen mit:
?~)!@
1101
: A impliziert B
? .
| @ !
) .
Dies ist viel einfacher als die gegenteilige Implikation, über die wir gerade gesprochen haben. Es ist wieder eines dieser horizontalen Zweigprogramme, wie das für and
. Wenn A
ja 0
, wird es einfach 1
auf den unteren Zweig erhöht und gedruckt. Andernfalls wird die oberste Verzweigung erneut ausgeführt, wobei diese stattdessen ?
gelesen B
und dann !
gedruckt wird.
Es gibt hier eine Menge Alternativen (insgesamt 66 Lösungen), hauptsächlich aufgrund der freien Wahl der effektiven No-Ops. Zunächst können wir die obige Lösung auf die gleiche Weise variieren, wie wir es könnten, and
und wir können auch wählen zwischen )
und 1
:
?.|@!) .?|@!) ?=|@!) =?|@!) ?_|@!) _?|@!) ?0|@!)
?.|@!1 .?|@!1 ?=|@!1 =?|@!1 ?_|@!1 _?|@!1 ?0|@!1
?.>@!) .?>@!) ?=>@!) =?>@!) ?_>@!) _?>@!) ?0>@!)
?.>@!1 .?>@!1 ?=>@!1 =?>@!1 ?_>@!1 _?>@!1 ?0>@!1
Und dann gibt es eine andere Version mit bedingter IP-Auswahl, bei der der erste Befehl fast willkürlich ausgewählt werden kann, und es gibt auch eine Auswahl zwischen )
und 1
für einige dieser Optionen:
"?#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
? $
@ # )
! <
Das letzte komplizierte. Wenn Sie noch lesen, haben Sie es fast geschafft. :) Lass uns zuerst schauen A = 0
:
?
liest A
und dann schlagen wir zu $
. Dies ist ein Sprungbefehl (wie der von Befunge #
), der den nächsten Befehl überspringt, damit wir nicht mit dem Befehl enden @
. Stattdessen geht die IP weiter bei #
. Da jedoch A
heißt 0
, tut dies nichts. )
erhöht es 1
so, dass die IP auf dem unteren Pfad fortgesetzt wird, auf dem das 1
gedruckt wird. Das <
lenkt die IP nach rechts um, wo sie in die linke Ecke übergeht und das Programm beendet wird.
Als nächstes, wenn die Eingabe ist, erhalten (A, B) = (1, 0)
wir diese Situation:
Es ist im Wesentlichen die gleiche wie zuvor , außer dass bei der #
wir auf IP - Switch 1
(grüne Strecke), aber da B
ist 0
man zurück zu IP wechseln , 0
wenn wir schlagen #
ein zweites Mal (jetzt blau - Pfad), wo er druckt 1
wie zuvor.
Schließlich der A = B = 1
Fall:
Dieses Mal, wenn wir #
das zweite Mal, ist der aktuelle Wert immer noch 1
so, dass wir die IP nicht erneut ändern. Das <
spiegelt es wieder und beim dritten Mal ?
bekommen wir eine Null. Daher wird die IP nach links unten umgebrochen, wo !
die Null ausgegeben wird und das Programm endet.
Insgesamt gibt es dafür neun 7-Byte-Lösungen. Die erste Alternative verwendet einfach 1
anstelle von )
:
?$@#1!<
Dann gibt es zwei Lösungen, die Ihnen bei der Menge an IP-Switching helfen:
)?#_[!@ 1?#_[!@
Dies hat mich wirklich umgehauen: Der interessante Teil ist, dass IP-Switching als verzögerte Bedingung verwendet werden kann. Die IP-Switching-Regeln der Sprache sehen vor, dass die aktuelle IP einen weiteren Schritt ausführt, bevor der Switch ausgeführt wird. Wenn dieser Schritt durch eine Ecke geht, entscheidet der aktuelle Wert darüber, auf welchem Zweig die IP fortgesetzt wird, wenn wir jemals wieder dorthin wechseln. Genau das passiert, wenn die Eingabe ist A = B = 1
. Obwohl dies alles im Einklang mit der Art und Weise steht, wie ich die Sprache entworfen habe, war mir diese Implikation der Spezifikation nie bewusst. Daher ist es schön, wenn mir meine Sprache einige neue Tricks beibringt: D.
Dann gibt es noch eine dritte Lösung, deren IP-Switching noch schlimmer ist (obwohl sie diesen aufgeschobenen bedingten Effekt nicht nutzt):
>?1]#!@
Und dann gibt es noch einen:
?$@#)!<
Und dann gibt es diese vier äquivalenten Lösungen, die eine nicht-bedingte IP-Umschaltung verwenden und stattdessen die gesamte Logik über Verzweigungen und Ecken implementieren:
]<?<@!) ]<?<@!1 ]|?<@!) ]|?<@!1
1111
: Wahr
1 !
@ . .
. .
Sie haben sich am Ende etwas Einfaches verdient: Kante setzen auf 1
, drucken mit !
, beenden mit @
. :)
Natürlich gibt es eine Alternative:
)!@
Wie üblich alle mit Timwis HexagonyColorer erstellten Kontrollflussdiagramme und das Speicherdiagramm mit seinem EsotericIDE .