Labyrinth , 28 25 24 23 22 Bytes
" >
?!?:|}\{@
@\?"":)!
Das hat wahnsinnig Spaß gemacht! :) Das ist mit Abstand das am dichtesten komprimierte Labyrinth-Programm, das ich bisher geschrieben habe. Ich hatte so viele Versionen mit 20 und 21 Bytes , die fast gearbeitet, ich bin immer noch Zweifel an diesen optimal ist ...
Dies nimmt Eingaben als Liste positiver Ganzzahlen (mit einem beliebigen Trennzeichen) und gibt das Ergebnis als durch Zeilenvorschub getrennte Ganzzahlen an STDOUT aus.
Die Jagd nach 20/21 Bytes: Ich habe alle Programme des Formulars überprüft
" XX
?!?X}\{@
@\?XX)!
Wo X
ist ein vernünftiger Charakter durch rohe Gewalt, aber keine gültigen Lösungen gefunden. Das bedeutet natürlich nicht, dass es keine kürzere Lösung gibt, aber es ist nicht möglich, 20-Byte-Programme zu erzwingen, ohne eine angemessene Menge von Annahmen für ihre Struktur zu treffen.
Erläuterung
(Die Erklärung ist etwas veraltet, aber ich bin immer noch nicht davon überzeugt, dass die Lösung optimal ist. Daher warte ich mit der Aktualisierung.)
Normalerweise sollen Labyrinth-Programme wie Labyrinthe aussehen. Während sich der Befehlszeiger in einem Korridor befindet, folgt er diesem Korridor. Wenn die IP auf eine beliebige Kreuzung trifft, wird die Richtung basierend auf dem oberen Wert des Labyrinth-Hauptstapels bestimmt (Labyrinth hat zwei Stapel mit einer unendlichen Anzahl von Nullen am unteren Rand). Das bedeutet normalerweise, dass jede nicht-triviale Schleife ziemlich teuer ist, denn wenn Sie überall Zellen ohne Wand haben, ist alles eine Kreuzung, und in den meisten Fällen hat die Oberseite des Stapels nicht den richtigen Wert für die IP den Weg einschlagen, den Sie einschlagen möchten. Sie vergrößern also die Schleifen so, dass sie ein Ganzes in der Mitte mit jeweils nur einem genau definierten Ein- und Ausgangspunkt haben.
Aber diesmal hatte ich wirklich Glück und alles passte so gut zusammen, dass ich alles zu einem großen Klumpen zerdrücken konnte. :)
Der Kontrollfluss beginnt _
nach Süden. Der _
drückt eine Null auf den Hauptstapel. Das mag wie ein No-Op erscheinen, erhöht aber die (nicht implizite) Stapeltiefe, 1
die wir später benötigen.
?
liest eine ganze Zahl aus STDIN. Wenn keine ganzen Zahlen mehr gelesen werden müssen, wird die Null verschoben. In diesem Fall bewegt sich die IP weiter nach Süden und @
beendet das Programm sofort (da die Eingabeliste leer ist). Ansonsten dreht sich die IP nach Osten.
Wir betreten jetzt eine sehr enge Schleife mit zwei Austrittspunkten:
!?;
\?
;
!
Gibt die Ganzzahl zurück zu STDOUT und belässt nur eine Null auf dem Stapel. Die IP bewegt sich weiter nach Osten und ?
liest die nächste Ganzzahl. Wenn das nicht Null ist, biegen wir rechts ab und bewegen uns nach Süden. ?
liest einen anderen (den nächsten geraden Index). Wenn das nicht Null ist, biegen wir rechts ab und ziehen nach Westen.
Dann wird \
ein Zeilenvorschub gedruckt, ohne den Stapel zu ändern, und wir biegen erneut rechts ab und bewegen uns nach Norden. !
Gibt die nächste gerade Index-Ganzzahl aus. Da es jetzt mindestens eine (positive) Ganzzahl mit ungeradem Index auf dem Stapel gibt, drehen wir weiter nach rechts und die Schleife wiederholt sich.
Sobald einer dieser ?
Punkte das Ende der Liste erreicht, drücken sie eine Null und bewegen sich direkt auf den entsprechenden ;
Punkt, der diese Null verwirft.
Für den Fall, dass es nur ein einziges Element in der Liste gab, sind wir fertig (weil wir das sofort gedruckt haben), sodass die IP den ganzen Weg nach Osten @
wandert und das Programm erneut beendet wird (Drucken eines Trailings) Zeilenvorschub unterwegs).
Andernfalls müssen wir auch die ungeraden Indexzahlen ausgeben. In diesem Fall verschmelzen die beiden Pfade (von den beiden Ausgangspunkten der ersten Schleife) in der Mitte "
und biegen in beiden Fällen nach Osten ab.
_
Drückt eine Null, um zu vermeiden, dass Sie nach links in das Feld gehen @
, und ;
verwirft diese Null. Nun betreten wir eine neue Schleife:
"}
""
Die IP-Adresse wird in der unteren linken Zelle eingegeben. Sie bewegt sich nach Norden und umläuft die Schleife im Uhrzeigersinn. Das }
verschiebt die Oberseite des Hauptstapels auf den Hilfsstapel. Solange sich noch ein Element auf dem Stack befindet, macht die IP weiter. Sobald alles auf den Zusatzstapel verschoben wurde (und in diesem Prozess umgekehrt wurde), bewegt sich die IP weiter nach Osten und tritt in die letzte Schleife ein:
\{@
#!
\
Druckt einen Zeilenvorschub erneut und {
verschiebt ein Element vom Hilfsstapel zurück zum Hauptstapel. Wenn das noch ein Element der Liste war, ist es positiv, und die IP dreht sich nach Süden, wo das Element mit gedruckt wird !
. Dann #
drückt die Stack - Tiefe (und das ist jetzt , wo die anfängliche _
wichtig ist, weil dies #
eine positive Stapeltiefe gewährleistet), so dass der IP noch nach rechts abbiegt, durch die \
und {
wieder.
Nachdem wir alles gedruckt haben, {
zieht die IP eine Null vom unteren Rand des Zusatzstapels nach Osten und @
beendet das Programm.