Eine kurze Geschichte der 2D-Programmiersprachen: 16 (+2) Jahre
v19977/2{@{{4{\_______>/02&&&#???? * P+++++1P1P-1P+1E * *
\'\02'oo100@n590@n; * * *
>"8991",,,;5-;,@ * * *
* * * *
\ * ++++++++++++++++++++++++ ++++++++++++++++++++++++ ++O--OO++++++++OX******* *
* #2018O@ * * * * * * *
* * * * * * * *
* * * * * * * *
* **** **** * **** **** * **** **** * **** *****
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * **** * * * * **** * * * * **** * * * * ****
* * * * * * * * * * * * * * * *
R"2014"; ***** ******* ****** ******* ****** ******* ****** *******
x
x%"2010"x
x
$'main' \/\/\/\
\-[2005]o-# \++++++\
/++++++/
\++++++\
/++++++/
\/\/\/\++.--..+++.#
S1^2^2^6^8MAOUOAOOF
/K:0:1:@
> "7102"4&o@
| }+++++[>++++++++++<-]>.--..++++++.@
Habe ich erwähnt, dass ich 2D-Programmiersprachen mag?
Die Sprache, mit der (angeblich im letzten Abschnitt) alles begann. In Befunge können Sie den Kontrollfluss mit umleiten <v>^
, aber die jetzt allgegenwärtigen Spiegel \
und /
waren noch keine Sache. Der Befunge-Interpreter von Anarchy Golf ignoriert unbekannte Befehle. Damit können wir die Familie Befunge von der Familie> <> unterscheiden. Daher lautet der von Befunge ausgeführte Code wie folgt:
v
\
>"8991",,,;5-;,@
Der "8991"
schiebt die einzelnen Zeichen auf den Stapel. ,,,
druckt die ersten drei aus. Dann ;
ist unbekannt (was wir benutzen, um es von Befunge 98 zu unterscheiden), 5-
verwandelt das 8
in ein 3
und ,
druckt das auch, bevor @
das Programm beendet wird.
Das Schreiben dieses Teils der Lösung hat wahrscheinlich so lange gedauert, bis ich alle anderen geschrieben und zusammengesetzt hatte ...
Wierd kennt nur zwei Symbole: Leerzeichen und alles andere. Der Anweisungszeiger versucht, dem Pfad zu folgen, der durch die Nicht-Leerzeichen gebildet wird, wobei er diagonal von der oberen linken Ecke beginnt und immer versucht, so gerade wie möglich zu verlaufen. Die Kurven im Pfad bilden die tatsächlichen Anweisungen (wobei die Gradzahl der Drehung bestimmt, welche Anweisung ausgeführt werden soll). Wierd sieht also folgenden Code:
v1997 * * *
' * * *
8 * * *
* * * *
* ++++++++++++++++++++++++ ++++++++++++++++++++++++ ++O--OO++++++++OX******* *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* **** **** * **** **** * **** **** * **** *****
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * **** * * * * **** * * * * **** * * * * ****
* * * * * * * * * * * * * * * *
***** ******* ****** ******* ****** ******* ****** *******
Das 1997
oben stehende wird nicht wirklich ausgeführt, aber Wierd lässt es uns aus dem Quellcode lesen, was viel kürzer ist als der Versuch, die Zeichencodes für die vier Ziffern selbst zu konstruieren (auch wenn es nicht so aussieht). .). Ich habe keine Lust, das Ganze zusammenzubrechen, aber Sie können die vier wiederholten Abschnitte deutlich sehen. Dies bedeutet, dass wir zuerst 1
auf dem Stapel speichern und dann in jedem dieser vier Abschnitte dies inkrementieren 1
und dann verzweigen. Der untere Ast drückt einen anderen1
, ruft das Quellzeichen an diesen Koordinaten ab und druckt es aus, während der obere Zweig zum nächsten Abschnitt umgeleitet wird. Sie mögen sich fragen, warum die Enden der Pfade so unnötig lang sind, aber das liegt daran, dass Wierd versucht, zu einem nahe gelegenen Pfad zu springen, bevor er entscheidet, dass der aktuelle Zweig beendet werden soll. Um dies zu vermeiden, müssen wir diese Enden weit genug von anderen Codes entfernen.
Befunge erhielt 1998 ein ziemlich bekanntes Update mit einer sehr strengen Spezifikation, die auf beliebige Dimensionen (und ich denke auch beliebige Topologien) verallgemeinert werden kann. Es ist jedoch weitgehend abwärtskompatibel mit Befunge, was es ziemlich einfach macht, die beiden zu polyglotten. Diese Befunge hatte noch keine Spiegel, daher ist der ausgeführte Pfad derselbe wie bei Befunge 93:
v
\
>"8991",,,;5-;,@
Der Unterschied ist, dass Befunge 98 das nicht ignoriert ;
. Stattdessen verhält es sich ein bisschen wie ein Kommentar, bei dem alle Befehle bis zum nächsten ;
ignoriert werden. Auf diese Weise, wir verringern das nicht 8
zu 3
und der Druck 1998
ist. Die
2001: Ein Space Od ... PingPong
2001 ist das Jahr von Piet, aber ich hatte wirklich keine Lust, eine Bilddatei mit all den anderen Programmen zu polyglotten, daher hier eine weniger bekannte 2D-Sprache. Es scheint ziemlich viele Funktionen zu haben (die wir nicht verwenden werden). Vielen Dank an Sp3000 für das Auffinden des Originaldolmetschers (der einzige tote Link in der archivierten Version der offiziellen Website).
PingPong ist insofern etwas ungewöhnlich, als es nur Spiegel und keine <v>^
Redirectors hat. Dieser bewegt sich also v19977
am Anfang durch den Spiegel und trifft dann auf den Spiegel, der ihn unten einwickelt. Der relevante Code lautet dann:
v19977/
...
/K:0:1:@
...
Der eigentliche Code ist ganz einfach: K
drückt 20
, die Ziffern drücken sich selbst, gibt :
eine ganze Zahl aus und @
beendet das Programm.
Dies ist die erste Sprache, in der es etwas einfacher wird, da SNUSP einen expliziten Einstiegspunkt unterstützt. Dieser Einstiegspunkt ist mit gekennzeichnet $
. Nach einigen Artikeln über Esolangs zu urteilen, hat diese Sprache einige andere inspiriert, aber letztendlich handelt es sich leider nur um ein Brainfuck-Derivat. Trotzdem denke ich, dass die Art und Weise, wie die aktuelle Zelle auf 48 gesetzt wird, ziemlich ordentlich ist (und aus dem Esolangs-Artikel gestohlen wurde). Hier ist der relevante Teil des Codes:
$'main' \/\/\/\
\++++++\
/++++++/
\++++++\
/++++++/
\/\/\/\++.--..+++.#
Das sind 24 +
s und die Spiegel senden die IP jeweils genau zweimal durch.
Aus welchem Grund auch immer, diese Sprache hat die haben <^>
Redirectoren aber statt der üblichen v
es verwendet %
. Dies bewegt sich also nur über die erste Zeile. Der relevante Code lautet:
v19977/2{@{{4{\
Wir geben zunächst einige Ziffern ein und führen eine Division durch. Dann 2{
druckt der 2
, @
löscht den Stapel. {{
druckt zwei (implizite) 0
s. 4{
druckt das 4
und \
beendet das Programm.
2005 war eine schwierige Wahl. In keinem anderen Jahr habe ich so viele 2D-Sprachen gefunden, und es gibt ADJUST und Archway, die beide in der unteren linken Ecke beginnen (was das Hinzufügen erleichtert hätte). Ich mag Rail, und da es einen expliziten Einstiegspunkt gibt, ist es auch nicht schwer, ihn hinzuzufügen. Rail sucht nach einer Startlinie $'main'
und beginnt, sich von der aus nach Südosten zu bewegen $
. Das heißt, der relevante Code lautet:
$'main'
\-[2005]o-#
Die \
und -
sind nur Tracks (No-Ops). Das [2005]
ist ein Zeichenkettenliteral, das o
gedruckt wird, bevor #
das Programm beendet wird.
Ein zweidimensionaler Brainfuck. Für dieses Jahr gibt es eine weitere interessante Sprache namens Schwarz, die bei der Koordinate (3,3)
(1-basiert) beginnt und die Verwendung dieser Sprache in einem Polyglott ebenfalls interessant gemacht hätte. Ich konnte jedoch keinen Dolmetscher finden. Also müssen wir stattdessen mit einem anderen BF-Derivat arbeiten ...
Das Interessante an diesem ist, dass es das Raster nicht wie die meisten anderen 2D-Sprachen in Linien mit Zeilenvorschüben formatiert. Stattdessen |
wird als Zeilentrennzeichen verwendet. Da ich |
keine anderen Sprachen verwendet habe, könnte ich einfach eine |
in die letzte Zeile setzen, wodurch der gesamte Rest des Programms für BF.js eine einzige Zeile wird. Der relevante Code lautet dann |
:
v19977/2{...
}+++++[>++++++++++<-]>.--..++++++.@
BF.js verwendet weder <v>^
Spiegel noch Spiegel. Die einzige Möglichkeit, den Kontrollfluss umzuleiten, besteht darin {}
, die IP-Richtung um 90 ° zu drehen. Diese Klammern verschieben also die IP in die zweite Zeile. Der Rest ist eine einfache Brainfuck-Lösung (nicht besonders gut gemustert), die eine Zelle auf 50
(Codepunkt von 2
) setzt und dann druckt, 2006
indem der Wert um ein Bit verschoben wird. @
Beendet das Programm.
Für dieses Jahr wollte ich unbedingt DOBELA verwenden, das mehrere Einstiegspunkte verwendet und wie das Liebeskind von Fission und Ziim aussieht . Leider konnte ich den Dolmetscher nicht zum Laufen bringen. Also hier ist ein weiteres BF-Derivat (das letzte, das ich verspreche).
Im Gegensatz zum letzten kennt dieser sowohl <v>^
als auch Spiegel, daher lautet der relevante Code:
v
\'\
8
\ * ++++++++++++++++++++++++ ++++++++++++++++++++++++ ++O--OO++++++++OX
Diese hat nicht die übliche BF-artige []
Schleife (stattdessen müssten Sie eine tatsächliche 2D-Schleife bilden), deshalb habe ich mich nur dafür entschieden, die fest zu codieren, 50
da ich sowieso eine Tonne Zeichen in einer Reihe von Wierd hatte. Beachten Sie, dass die '
und 8
ignoriert werden, das *
ist ein bedingtes Trampolin, das wir ignorieren können, und das O
ist Brainfucks .
. Der X
beendet das Programm.
Wahrscheinlich das beliebteste Fungeoid (außer Befunge selbst) zumindest in dieser Gegend. > <> hat sowohl <v>^
Spiegel als auch Zeichenkettenliterale. Der ausgeführte Code lautet also:
v
\'\02'oo100@n590@n;
Das String-Literal dient hauptsächlich zum Überspringen der \
Zeichen, die wir für BrainSpace 1.0 verwendet haben, aber während wir dabei sind, können wir auch die ersten beiden Zeichen eingeben. oo
druckt sie aus. Dann 100
drückt man drei Ziffern, @
schiebt die obere nach unten und n
druckt die 0
Unterseite. Wir machen das selbe nochmal mit 590
dem der druckt 9
. Wenn Sie sich fragen, warum ich nicht einfach so drucke 2009
, warten Sie auf 2015. ;
Beendet das Programm.
Dieses war einfach, weil es einen expliziten Einstiegspunkt bei hat %
. Dieser erstellt jedoch 4 IPs in alle Richtungen (daher der Name der Sprache, nehme ich an), und wir müssen 3 davon entfernen. Hier ist der relevante Code:
x
x%"2010"x
x
Gut ja. (In Cardinal wird im Zeichenfolgenmodus direkt gedruckt, anstatt die Zeichen auf einem Stapel abzulegen.)
Eine weitere Sprache mit einem expliziten Einstiegspunkt (von David Catt, der einige andere sehr nette Esolangs erstellt hat), diesmal um S
. Dies macht den relevanten Code zu diesem Teil:
S1^2^2^6^8MAOUOAOOF
RunR ist etwas interessant, da die meisten Operationen mit einer Art Register arbeiten und Werte für Binäroperationen explizit in den Stack verschoben werden müssen. Die Ziffern setzen die Registerwerte auf sich selbst und verschieben ^
das aktuelle Register in den Stapel. Dann M
erfolgt die Multiplikation (Register-Zeiten-Wert aus dem Stapel), U
die Subtraktion, A
die Addition und O
die Ausgabe. F
Beendet das Programm.
Wie Wierd versucht Ropy, Abschnitten von Nicht-Leerzeichen zu folgen, aber hier bestimmen die Kurven nicht die Befehle. Tatsächlich stellt sich heraus, dass Ropy meinem eigenen Labyrinth ähnlicher ist, da die gewählte Richtung von der Oberseite des Stapels abhängt. Darüber müssen wir uns hier jedoch nicht wirklich Gedanken machen, denn Ropy bewegt sich einfach entlang der ersten Zeile:
v19977/2{@{{4{\_______>/02&&&#????
Es gibt eine Menge Dinge, die wir ignorieren können >
. Alles, was wir wissen müssen, ist, dass der obere Teil des Stapels zu diesem Zeitpunkt a ist 4
und dass er 2
unten liegt.
>
dupliziert das 4
, /
macht Division daraus ein 1
. Dann schieben wir 02
. &&&
Verbindet die oberen vier Zahlen des Stapels in umgekehrter Reihenfolge und gibt 2012
. #
gibt es aus. ????
Löscht nur den Stapel, da sonst auch der obere Teil des Stapels ausgegeben wird.
Ein Punkt von Interesse ist , dass der zweite 7
in 19977
wurde hinzugefügt , weil der ropy. Die /
Unterteilung in Ropy macht top / second
(entgegen der üblichen Reihenfolge in vielen Stack-basierten Sprachen), wo 7 / 9
es geben würde 0
. Wenn wir oben auf dem Stapel eine Null hätten, würde Ropy ein paar wilde Dinge mit seiner Bewegungsrichtung anstellen, also müssen wir die andere drängen, 7
um sicherzustellen, dass die Oberseite des Stapels positiv bleibt und Ropy sich weiter nach Osten bewegt.
Mit seinen expliziten Einstiegspunkten ist dieser einfach. RDLU
Erzeugen Sie Atome (Anweisungszeiger) in der entsprechenden Richtung. Das relevante Bit ist also genau dies:
R"2014";
Beachten Sie, dass es auch einen U
im Quellcode gibt, dieser Atom jedoch irgendwann einen *
von Wierd trifft , wodurch das Programm beendet wird (und dieser Atom dauert viel länger als der R
Druck 2014
).
Das mächtigere> <> Derivat von Sp3000. Es ist weitgehend abwärtskompatibel mit> <>, daher ist der ausgeführte Code immer noch:
v
\'\02'oo100@n590@n;
Die Drehrichtung von @
wurde jedoch geändert. Dies ist der Standardtrick zur Unterscheidung von> <> und Gol> <> in Polyglots. Daher wird dieser Trick 15
anstelle von gedruckt 09
. Daher die Verrücktheit in der zweiten Hälfte des Programms.
CSL ist insofern sehr interessant, als Befehle nicht sofort ausgeführt werden. Stattdessen wird jeder Befehl auf einen Befehlsstapel verschoben e
und E
kann verwendet werden, um Befehle von diesem auszuführen. Der relevante Code wird:
v19977/2{@{{4{\_______>/02&&&#???? * P+++++1P1P-1P+1E
Der E
führt also den gesamten Befehlsstapel aus, was bedeutet, dass das Zeug davor in umgekehrter Reihenfolge ausgeführt wird. Wir müssen uns nur um Folgendes kümmern *
:
1+P1-P1P1+++++P*
Die 1
s schieben sich auf den Datenstapel. +
und -
sind Dekrement / Inkrement. P
druckt die Oberseite des Stapels. Dann wird *
versucht, die beiden obersten Werte des Stapels zu multiplizieren. Der Stack ist jedoch leer, so dass das Programm beendet wird.
An diesem Punkt kommen wir zu den Sprachen, die nach dem Veröffentlichen dieser Herausforderung veröffentlicht wurden. Daher zähle ich sie nicht wirklich für die Punktzahl, zumal ich sie selbst erstellt habe (allerdings nicht mit Blick auf diese Herausforderung). Sie verfügen jedoch über einige neuartige IP-Bewegungssemantiken, die es einfach machten, sie in die Mehrsprachigkeit einzufügen, und die diesem Schaufenster von 2D-Sprachen etwas Interessantes hinzufügten.
Alice wurde entworfen, um ein Fungeoid mit vielen Funktionen zu sein. Ein interessanter Unterschied zu den meisten (aber nicht allen) anderen 2D-Sprachen besteht darin, dass sich die IP entweder orthogonal oder diagonal bewegen kann. Durch das Umschalten zwischen diesen Befehlen wird auch die Semantik fast aller Befehle in der Sprache geändert. Darüber hinaus unterstützt Alice sowohl die traditionellen <^>v
Richtungssetzer als auch die \/
Spiegel, aber Spiegel haben in Alice ein sehr einzigartiges Verhalten (wodurch es einfach ist, die Alice-IP zu einem bislang nicht verwendeten Teil des Codes zu führen).
Während der meisten Sprachen behandeln \
und , /
als ob sie von Spiegeln in einem Winkel von 45 °, und die IP als Lichtstrahl aus der es Prellen, behandelt Alice sich als einen 67,5 ° Winkel (der den Winkel des tatsächlichen slash Glyphen näher ist) und die IP bewegt sich auch durch den Spiegel (daher der Name der Sprache). Aufgrund dieses Winkels wechseln die Spiegel zwischen Bewegungen in orthogonalen oder diagonalen Richtungen. Im Ordinal-Modus (dh während sich die IP entlang der Diagonalen bewegt) springt das Gitter nicht umher und stattdessen springt die IP von den Rändern ab (während sie im Cardinal-Modus umher springt).
Alles in allem ist der von Alice ausgeführte Code der folgende:
v19
\ \
...
> "7102"4&o@
...
Die IP beginnt wie gewohnt in der linken oberen Ecke, v
schickt sie nach Süden. Jetzt \
reflektiert das IP, um sich nach Nordwesten zu bewegen, wo es sofort vom linken Rand des Gitters abprallt (und sich stattdessen nach Nordosten bewegt). 1
ignoriert werden kann, prallt die IP von der oberen Kante ab, um sich als nächstes nach Südosten zu bewegen. Wir treffen einen anderen, \
der die IP Nord widerspiegelt. 9
kann auch ignoriert werden und die IP wird dann an den unteren Rand des Gitters verschoben. Nach ein paar Zeilen leiten wir es >
aus Bequemlichkeitsgründen nach Osten um. Dann "7102"
drückt der die Codepunkte 2017
, 4&o
druckt diese vier Zeichen und @
beendet das Programm.
Wumpus ist die erste 2D-Sprache in einem Dreiecksgitter, die die Bewegung durch den Code ganz anders macht (und uns wieder leicht zu einem unbenutzten Teil des Codes gelangen lässt). Anstatt sich jedes Zeichen im Raster als kleines Quadrat vorzustellen, sollten Sie sie als abwechselnde Dreiecke nach oben und unten betrachten. Die linke obere Ecke ist immer ein Dreieck nach oben.
Wumpus hat keine Richtungssetzer wie <^>v
, aber es hat Spiegel \/
. Aufgrund des dreieckigen Rasters funktionieren diese jedoch anders als die meisten anderen Sprachen. Die IP prallt von ihnen ab wie ein Lichtstrahl (wie üblich), aber Sie sollten sich vorstellen, dass sie einen Winkel von 60 ° haben. Ein IP, das sich nach Osten bewegt, bewegt sich am Ende entlang der Nordwestachse des Gitters.
Ein weiterer Unterschied zu den meisten anderen Sprachen besteht darin, dass die Kanten des Rasters nicht umbrochen werden, sondern dass die IP-Adresse stattdessen von den Kanten abprallt (als ob diese Kantenzellen die entsprechenden Spiegel enthalten würden). Ein weiteres lustiges kleines Detail ist, dass Diagonalen durch das Dreiecksgitter tatsächlich wie Treppen im Quellcode aussehen.
In diesem Sinne sieht der von Wumpus ausgeführte Code wie folgt aus (wobei ich .
aus Gründen der Übersichtlichkeit Leerzeichen durch ersetzt habe :
v19977/
02
89
..
..
.....*...#2018O@
Das v19977
sind nur Schrott, den wir ignorieren können. /
sendet die IP nach Nordwesten, wo sie sich 977
(von rechts) erneut bewegt, während sie von der oberen Kante abprallt. Dann bewegt sich die IP nach Südwesten durch die 2089
und eine Reihe von Räumen, bevor sie den linken Rand trifft, um wieder nach Osten reflektiert zu werden. *
ist auch Müll. Dann endlich #2018
drückt 2018
, O
druckt und @
beendet das Programm.
Fehlende Jahre
Zum Schluss einige Anmerkungen zu Jahren, die ich nicht behandelt habe.
Als ich über die Jahre nach geeigneten 2D-Sprachen suchte, die in einem Polyglott verwendet werden konnten, stellte ich fest, dass Befunge entgegen der landläufigen Meinung nicht die erste 2D-Sprache war. Dieser Titel scheint von Biota gehalten zu werden, der bereits 1991 erstellt wurde. Leider hat die Sprache keine Ausgabe, so dass ich ihn für diese Herausforderung nicht verwenden konnte.
Soweit ich weiß, wurden 1992 und 1995 keine 2D-Sprachen erstellt. Daher habe ich einige Jahre nicht behandelt:
- 1994: Orthagonal wird unabhängig von Befunge gegründet. Die Sprachen sind semantisch ziemlich ähnlich, aber Orthagonal legt den Quellcode nicht in 2D an. Stattdessen ist jede Zeile ein
(x, y, instruction)
Tupel. Ich habe sogar die Sprachspezifikation und den Originalinterpreter vom Schöpfer Jeff Epler erhalten, aber am Ende machte die Tatsache, dass die Syntax nicht 2D ist, die Sprache für diesen Polyglott ungeeignet.
- 1996: Orthogonal , ein Nachfolger von Orthagonal (von jemand anderem erstellt), wurde erstellt, aber für die Zwecke dieses Polyglots treten die gleichen Probleme auf wie bei Orthagonal.
- 1999: Die einzige Sprache, die ich finden konnte, war Chris Presseys Handy- Automat REDGREEN . Leider scheint es im Gegensatz zu seinem Vorgänger RUBE keine I / O-Semantik zu haben.
- 2000: Es gibt einen anderen Zellularautomaten von Chris Pressey, der noit o'mnain worb heißt, aber auch keinen I / O hat. Es gibt auch Numberix, das ich nicht zum Laufen gebracht habe, und ich bin mir nicht sicher, ob es nicht-hexadezimale Zeichen im Quellcode ignorieren würde.
- 2002: Es gibt Clunk ohne E / A und ZT, dessen Sprachspezifikation mich erschreckt.
- 2007: Ich habe hier drei Sprachen gefunden. Zetaplex ist bildbasiert (also nein) und RubE On Conveyor Belts scheint einen Header mit einem ziemlich strengen Format zu erfordern, der mit der ersten Zeile des Programms durcheinander gekommen wäre. Es gibt auch Cellbrain von Quintopia, aber es scheint auch einen bestimmten Header zu erfordern.
- 2013: Wieder habe ich drei Sprachen gefunden. Das Fischen könnte mit einer guten Restrukturierung möglich sein, aber es würde erfordern, dass das Programm mit einem gültigen Dock beginnt. Aus dem Gedächtnis betrachtet, ist Quipu in seiner Syntax viel zu streng, um viel Polyglotten zuzulassen. Und Swordfish ist ein weiteres Mitglied der Familie> <>, aber leider konnte ich keinen Dolmetscher finden. Andernfalls wäre dies wahrscheinlich ziemlich einfach hinzuzufügen.
Wenn jemand Interesse hat, ist hier die vollständige Liste der implementierten 2D-Sprachen, sortiert nach Jahren , soweit ich sie finden konnte (zu dem Zeitpunkt, als diese Antwort gepostet wurde). Wenn welche in dieser Liste fehlen, lass es mich bitte im Chat wissen, da ich wirklich an einer vollständigen Liste interessiert bin.