:-:_
Probieren Sie es online! In der Fußzeile habe ich alle anderen 4-Byte-Lösungen aufgenommen. (Stack Cats ignoriert alles nach dem ersten Zeilenvorschub.)
Versuchen Sie das Gegenteil!
Erläuterung
Das -n
Flag aktiviert die numerische Ausgabe (und Eingabe, aber wir haben keine), und das -m
Flag ist normalerweise nur ein Vorteil beim Golfen, mit dem Sie den redundanten Teil des Quellcodes vermeiden können. Dies liegt daran, dass jedes Stack Cats-Programm Spiegelsymmetrie haben muss. Mit der -m
Flagge geben Sie nur die erste Hälfte (plus das zentrale Zeichen). Das eigentliche Programm hier ist also:
:-:_:-:
Wie Sie im ersten TIO-Link sehen können, gibt es eine Menge 4-Byte-Lösungen, aber ich habe diese wegen ihrer Einfachheit ausgewählt. Stack Cats ist stapelbasiert und dieses Programm verwendet nur den Anfangsstapel. Da wir keine Eingabe haben, enthält es eine einzelne -1
(einen EOF-Marker) auf einer unendlichen Nullmulde. Die drei Befehle im Programm haben folgende Bedeutung:
: Swap the top two stack elements.
- Negate the top stack element (i.e. multiply by -1).
_ Pop a. Peek b. Push b-a.
So ändert das Programm den Stapel (Zustände und Befehle sind gestaffelt, um anzuzeigen, wie jeder Befehl den Stapel von einem Zustand zum nächsten ändert):
: - : _ : - :
-1 0 0 -1 1 0 0 1
0 -1 -1 0 0 1 1 0
0 0 0 0 0 0 0 0
… … … … … … … …
Wie sich herausstellt, ist der einzige Befehl, der hier wirklich etwas tut, _
der unseren EOF-Marker in einen verwandelt 1
. Die Ausgabe am Ende des Programms ist implizit, und der EOF-Marker ist optional. Dadurch wird nur das ausgegeben, was 1
wir erhalten.
Wenn wir nun den Quellcode aufgrund der impliziten Spiegelung umkehren, wird das eigentliche Programm:
_:-:-:_
Das macht etwas ganz anderes:
_ : - : - : _
-1 1 0 0 1 -1 0 -1
0 0 1 1 0 0 -1 -1
0 0 0 0 0 0 0 0
… … … … … … … …
Diesmal ist der Boden des Stapels immer noch ein, -1
sodass er als EOF-Marker fungiert und nur der -1
obere Rand gedruckt wird.
...
Nun, da Stack Cats eine so einzigartige Beziehung zum Umkehren von Code hat, halte ich das Verwenden -m
für ein bisschen betrügerisch. Es ist normalerweise nur dazu gedacht, Bytes zu sparen, indem der redundante Teil des Quellcodes weggelassen wird, aber hier macht es die Herausforderung tatsächlich viel einfacher und sogar das gesamte Programm kürzer. Dies liegt daran, dass das Umkehren eines vollständigen Programms das Programm nur dann ändert, wenn es eines von enthält <>[]
, was auch bedeutet, dass das Programm mehrere Stapel verwendet (Stack Cats hat tatsächlich ein Stapelband, in dem alle außer dem ersten nur gefüllt sind mit Nullen zu beginnen). Wenn Sie es umkehren, werden außerdem nur die Paare <>
und []
vertauscht, wodurch die Ausführung immer noch symmetrisch wird. Die einzige Möglichkeit, diese Symmetrie zu durchbrechen, ist die Verwendung von I
which does -]
oder-[
oder nichts, je nach dem Zeichen auf der Oberseite des Stapels. So...
*|]I*:*I[|*
Probieren Sie es online! Die Fußzeile enthält wieder alle anderen Alternativen mit derselben Byteanzahl. Einige davon geben 1 / -1 und einige 2 / -2 aus, wie nach jedem Programm angegeben. Ich habe dieses ausgewählt, um es zufällig als eines von denen zu erklären, die 2 ausgeben.
Versuchen Sie das Gegenteil!
Erläuterung
Wie gesagt, das ist etwas länger. Selbst wenn wir die -m
Notation dafür verwenden würden, würde sie 6 Bytes anstelle der obigen 4 wiegen.
Die Befehle, die diesmal verwendet werden:
* Toggle the least significant bit of the top of the stack.
| Reverse the longest non-zero of prefix on this stack.
[] Move one stack to the left/right and take the top of the current stack with you.
I If the top of the stack is positive, -], if it's negative, -[, otherwise do nothing.
: Swap the top two stack elements.
Das erste Programm verwendet nur zwei Stapel. In der ASCII-Kunst ist das ein bisschen chaotisch, aber ich werde mein Bestes geben. Die eckigen Klammern geben an, auf welchem Stapel sich der Bandkopf befindet, und ich setze die Befehle zwischen die einzelnen Stapelzustände.
[-1]
… 0 0 …
0 0
… …
*
[-2]
… 0 0 …
0 0
… …
| (does nothing)
]
[-2]
… 0 0 …
0 0
… …
I
[2]
… 0 0 …
0 0
… …
*
[3]
… 0 0 …
0 0
… …
:
[0]
… 3 0 …
0 0
… …
*
[1]
… 3 0 …
0 0
… …
I
[-1]
… 3 0 …
0 0
… …
[
[-1]
… 3 0 …
0 0
… …
|
[ 3]
… -1 0 …
0 0
… …
*
[ 2]
… -1 0 …
0 0
… …
Jetzt -1
fungiert der als EOF-Marker und der 2
wird gedruckt.
Das andere Programm ist bis zum [
. Bis zur zweiten ist es praktisch immer noch dasselbe I
. Wir werden technisch gesehen auf einem anderen Stack sein, aber ohne Werte sind sie alle nicht zu unterscheiden. Aber dann kommt es auf den Unterschied zwischen I[
und an I]
:
*|[I*:*I
[-1]
… 3 0 0 …
0 0 0
… … …
]
[-1]
… 3 0 0 …
0 0 0
… … …
| (does nothing)
*
[-2]
… 3 0 0 …
0 0 0
… … …
Und dieses Mal haben wir keinen EOF-Marker, aber das Programm gibt immer noch den aus -2
.
-
umkehren könnten, arbeitet das eine Byte (0x45 = 0b00101101) in Jelly --
ergibt -1, da es das Literal -1 definiert, währendṆ
(0xB4 = 0b10110100) 1 ergibt, da es ein logisches Nein ausführt der impliziten Eingabe von Null. (Funktioniert natürlichṆ
genauso gut: p)