:?
:
#/)
\ #
!"*@
"
Probieren Sie es online!
Dies gibt die Ergebnisse in der C, B, A
durch Zeilenvorschübe getrennten Reihenfolge aus.
Erläuterung
Wie immer ein kurzer Labyrinth-Primer:
- Labyrinth hat zwei Stapel von Ganzzahlen mit willkürlicher Genauigkeit, main und aux (iliary), die anfänglich mit einer (impliziten) unendlichen Menge von Nullen gefüllt sind. Wir werden main nur für diese Antwort verwenden.
- Der Quellcode ähnelt einem Labyrinth, in dem der Anweisungszeiger (IP) nach Möglichkeit Korridoren folgt (sogar um Ecken). Der Code beginnt beim ersten gültigen Zeichen in der Lesereihenfolge, in diesem Fall also in der linken oberen Ecke. Wenn die IP zu einer beliebigen Art von Junction gelangt (dh zu mehreren benachbarten Zellen zusätzlich zu derjenigen, von der sie stammt), wählt sie eine Richtung aus, die auf der Oberseite des Hauptstapels basiert. Die Grundregeln sind: links abbiegen, wenn negativ, weiterfahren, wenn null, rechts abbiegen, wenn positiv. Und wenn eine davon nicht möglich ist, weil es eine Mauer gibt, dann geht die IP in die entgegengesetzte Richtung. Die IP dreht sich auch um, wenn Sackgassen getroffen werden.
Trotz der beiden No-Ops ("
), die das Layout etwas verschwenderisch erscheinen lassen, bin ich mit dieser Lösung ziemlich zufrieden, da der Steuerungsfluss tatsächlich ziemlich subtil ist.
Die IP beginnt in der oberen linken Ecke auf der :
rechten Seite. Es wird sofort eine Sackgasse auf dem ?
und umdrehen, so dass das Programm tatsächlich mit diesem linearen Stück Code beginnt:
: Duplicate top of main stack. This will duplicate one of the implicit zeros
at the bottom. While this may seem like a no-op it actually increases
the stack depth to 1, because the duplicated zero is *explicit*.
? Read n and push it onto main.
: Duplicate.
: Duplicate.
Das heißt, wir haben jetzt drei Kopien n
auf dem Hauptstapel, aber die Tiefe ist 4
. Das ist praktisch, weil wir so die Stapeltiefe bestimmen können, um den aktuellen Multiplikator abzurufen, während wir die Kopien der Eingabe durcharbeiten.
Die IP tritt nun in eine (im Uhrzeigersinn) 3x3-Schleife ein. Beachten Sie, dass #
die Stapeltiefe immer einen positiven Wert liefert, sodass wir wissen, dass die IP an diesem Punkt immer nach Osten zeigt.
Der Schleifenkörper lautet wie folgt:
# Push the stack depth, i.e. the current multiplier k.
/ Compute n / k (rounding down).
) Increment.
# Push the stack depth again (this is still k).
* Multiply. So we've now computed (n/k+1)*k, which is the number
we're looking for. Note that this number is always positive so
we're guaranteed that the IP turns west to continue the loop.
" No-op.
! Print result. If we've still got copies of n left, the top of the
stack is positive, so the IP turns north and does another round.
Otherwise, see below...
\ Print a linefeed.
Then we enter the next loop iteration.
Nachdem die Schleife !
dreimal (bis zu ) durchlaufen wurde, sind alle Kopien von n
verbraucht, und die Null darunter wird angezeigt. Aufgrund der"
am unteren Rand (die sonst ziemlich nutzlos erscheint) ist diese Position eine Abzweigung. Das heißt, mit einer Null oben auf dem Stapel versucht die IP, geradeaus (nach Westen) zu fahren, aber da es eine Wand gibt, dreht sie sich tatsächlich um 180 Grad und bewegt sich nach Osten zurück, als hätte sie eine Sackgasse erreicht.
Infolgedessen wird jetzt das folgende Bit ausgeführt:
" No-op.
* Multiply two zeros on top of the stack, i.e. also a no-op.
The top of the stack is now still zero, so the IP keeps moving east.
@ Terminate the program.
C B A
), wenn dies in der Antwort eindeutig angegeben ist?