Weil wir nicht genug von esoterischen Golfspielen bekommen können, oder?
/// - Ausgesprochene Schrägstriche - ist eine lustige kleine Sprache, die auf der s///
Regex-Ersetzungsfunktion von Perl Fame basiert . Es enthält nur zwei Sonderzeichen, Schrägstrich /
und Backslash \
. Sie können einen vollständigen Artikel im esolangs-Wiki finden , aber ich werde eine Beschreibung der Sprache unten sowie einige Beispiele wiedergeben.
Kurz gesagt, es funktioniert, indem es sich /pattern/repl/rest
im Programm identifiziert und die Substitution so oft wie möglich durchführt. Es gibt keine Sonderzeichen außer /
und \
: /
Beschreibt Muster und Ersetzungen im Programm, während \
Sie Literal /
oder \
Zeichen in Ihren Code einfügen können. Insbesondere handelt es sich hierbei nicht um reguläre Ausdrücke, sondern nur um einfache Zeichenfolgensubstitutionen.
Ihre Herausforderung besteht darin, einen Interpreter für die Sprache /// zu erstellen, entweder als Programm, das STDIN liest, oder als Funktion, die ein Zeichenfolgenargument mit möglichst wenigen Zeichen verwendet.
Sie können eine beliebige Sprache außer /// verwenden. Sie dürfen keine Bibliotheken verwenden, die ///; Sie können jedoch reguläre Ausdrücke, reguläre Ausdrücke oder Bibliotheken mit übereinstimmenden Zeichenfolgen verwenden.
Ausführung
Es gibt vier Zustände: Drucken , Muster , Ersetzen und Ersetzen . In jedem Staat außer Substitution :
- Wenn das Programm leer ist, wird die Ausführung angehalten.
- Ansonsten, wenn das erste Zeichen ist
\
, machen Sie etwas mit dem nächsten Zeichen (falls vorhanden) und entfernen Sie beide aus dem Programm. - Andernfalls
/
entfernen Sie das erste Zeichen und wechseln in den nächsten Status. - Ansonsten mache etwas mit dem ersten Zeichen und entferne es aus dem Programm.
- Wiederholen.
Die Zustände durchlaufen nacheinander Druck , Muster , Ersetzung und Ersetzung .
- Im Druckmodus bedeutet "etwas tun" die Ausgabe des Zeichens.
- Im Pattern- Modus bedeutet "etwas tun", das Zeichen zum aktuellen Pattern hinzuzufügen.
- Im Ersetzungsmodus bedeutet "etwas tun", dass das Zeichen zum aktuellen Ersetzungsmodus hinzugefügt wird.
Im Substitutionsmodus folgen Sie anderen Regeln. Ersetzen Sie wiederholt das erste Auftreten des aktuellen Patterns durch das aktuelle Replacement im Programm, bis keine Substitutionen mehr möglich sind. Löschen Sie zu diesem Zeitpunkt das Muster und den Ersatz und kehren Sie zum Druckmodus zurück .
Im Programm /foo/foobar/foo foo foo
passiert folgendes:
/foo/foobar/foo foo foo
foo foo foo
foobar foo foo
foobarbar foo foo
foobarbarbar foo foo
...
Dies führt eine Endlosschleife durch und beendet den Substitutionsmodus nie . Wenn das Pattern leer ist, stimmt das erste Vorkommen der leeren Zeichenfolge - am Anfang des Programms - immer überein, sodass der Substitutionsmodus für immer wiederholt wird und niemals anhält.
Beispiele
no
Ausgang: no
.
/ world! world!/Hello,/ world! world! world!
Ausgang: Hello, world!
.
/foo/Hello, world!//B\/\\R/foo/B/\R
Ausgang: Hello, world!
.
a/ab/bbaa/abb
Ausgang: a
. Programm stoppt nicht.
//
Ausgabe: keine.
///
Ausgabe: keine. Programm stoppt nicht.
/\\/good/\/
Ausgang: good
.
Es gibt auch eine Quine im Wiki, die du ausprobieren kannst.
quelle
/-/World//--/Hello//--W/--, w/---!
Was gibt es nicht zu lieben? (Versuchen Sie, die Bindestriche am Ende zu entfernen.)\
Zeichen entfernt sich von allen darauf folgenden Zeichen, einschließlich/
der Zeichen , die später wie gewohnt verwendet werden können. Das sieht zwar nicht nach viel aus, macht aber Turing komplett .///
IDE, die ich mache!Antworten:
APL (133)
Dies ist eine Funktion, die den
///
Code als das richtige Argument verwendet.Ungolfed mit Erklärung:
quelle
///
und//foo/
(dh Endlosschleifen)?/
würde das an diesem Punkt noch übrig bleiben.J -
181190170 charDas war ein Albtraum. Ich habe es zweimal von Grund auf neu geschrieben, weil es mich immer wieder nervte. Dies ist eine Funktion, die ein einzelnes Zeichenfolgenargument verwendet und an STDOUT ausgibt.
Um es zu erklären, werde ich es in Unterausdrücke aufteilen.
i
(kurz für iterate ) ist ein Adverb. Es nimmt ein Verbargument auf der linken Seite und gibt ein Verb zurück(f)i
, das, wenn es auf ein Argument angewendet wird,f
wiederholt auf das Argument angewendet wird, bis eines von zwei Dingen eintritt: Es findet einen festen Punkt (y = f y
) oder es löst einen Fehler aus. Das Festkommaverhalten ist inhärent^:_
und::]
führt die Fehlerbehandlung durch.parse
Tokenisiert die Eingabe in das, was ich als halb geparste Form bezeichne, und schneidet sie dann am nicht entkoppelten '/' ab. Es bindet entstehende Backslashes an ihre Charaktere, entfernt die Backslashes jedoch nicht - wir können sie also entweder rückgängig machen oder beenden, je nachdem, was wir wollen.Der Großteil der interessanten Arbeit fällt in
;:
. Dies ist ein sequentielles Maschineninterpreter-Grundelement,(0;(0,:~1 0,.2);'\';&<1 0)
das links eine Beschreibung der Maschine ( ) und rechts eine Analyse vornimmt. Dies führt die Tokenisierung durch. Ich werde bemerken, dass diese spezielle Maschine tatsächlich das erste Zeichen unspezifisch behandelt, auch wenn es sich um ein handelt\
und binden sollte. Ich mache das aus ein paar Gründen: (1) die Zustandstabelle ist einfacher, so dass man weiter Golf spielen kann; (2) Wir können der Vorderseite ganz einfach einen Dummy-Charakter hinzufügen, um dem Problem auszuweichen. und (3) dieses Dummy-Zeichen wird ohne zusätzliche Kosten zur Hälfte analysiert, damit ich es als nächstes für die Schneidephase einrichten kann.Wir verwenden
<;._1
diese Option auch , um das Token-Ergebnis auf "Unescaped" zu schneiden/
(was ich als erstes Zeichen auswähle). Dies ist praktisch, um die Ausgabe, das Muster und den Austauschout/patt/repl/rest
in einem Schritt zu erledigen, schneidet aber leider auch den Rest des Programms ab, wo wir diese benötigen/
, um unangetastet zu bleiben. Ich spleiße diese währenddessen wieder eineval
, weil es<;._1
viel mehr kostet, sie in Ruhe zu lassen.Die Fork
(eval [ print)
führtprint
das Ergebnisparse
für seine Nebenwirkungen aus und läuft danneval
.print
ist ein einfaches Verb, das die erste Box öffnet (die, von der wir sicher wissen, dass sie ausgegeben wird), die Analyse beendet und sie an STDOUT sendet. Wir nutzen jedoch auch die Möglichkeit, ein Utility-Verb zu definierenp
.p
ist definiert als>@{.@[
, also nimmt es sein linkes Argument (verhält sich wie die Identität, wenn nur ein Argument angegeben wird), nimmt das erste Element davon (Identität, wenn ein Skalar angegeben wird) und entpackt es (Identität, wenn es bereits entpackt ist). Dies wird sehr praktisch seinsub
.eval
wertet den Rest des abgearbeiteten Programms aus. Wenn wir kein vollständiges Muster oder keine vollständige Ersetzung haben,eval
wirft es aus und gibt nur eine leere Liste zurück, die die Auswertung beendet, indem bei der nächsten Iteration ein;:
(fromparse
) -Fehler ausgegeben wird. Else,eval
parst vollständig um das Muster und den Ersatz, korrigiert den Rest der Quelle, und übergibt dann sowohl ansub
. Durch Explosion:sub
Hier findet eine (möglicherweise unendliche) Substitutionsrunde statt. Aufgrund der Art und Weise, wie wir eingerichtet habeneval
, ist die Quelle das richtige Argument, und das Muster und die Ersetzung sind in der linken Spalte zusammengefasst. Da die Argumente in dieser Reihenfolge angeordnet sind und wir wissen, dass sich Muster und Ersetzung innerhalb einer Ersetzungsrunde nicht ändern, können wir ein weiteres Merkmal deri
Delegierung verwenden - nämlich die Tatsache, dass nur das richtige Argument geändert wird und weiterhin dasselbe links übergeben wird für J die Notwendigkeit, sich Sorgen zu machen, den Staat im Auge zu behalten.Es gibt jedoch zwei Probleme. Das erste ist, dass J-Verben höchstens zwei Argumente haben können, so dass wir keinen einfachen Weg haben, auf alle zuzugreifen, die hier gebündelt sind, wie Muster und Ersetzung. Durch den geschickten Einsatz des von
p
uns definierten Dienstprogramms ist dies kein so großes Problem. Tatsächlich können wir auf das Muster in einem Zeichen zugreifen, indem wirp
aufgrund seiner>@{.@[
Definition einfach Folgendes verwenden: das Unbox-Feld des ersten Elements des linken Arguments. Das Erhalten des Ersatzes ist schwieriger, aber der kürzeste Weg wärep&|.
, 2 Zeichen kürzer als manuelles Herausholen .Das zweite Problem ist, dass es
i
auf festen Punkten endet, anstatt für immer zu schleifen. Wenn das Muster und die Ersetzung gleich sind und Sie eine Ersetzung vornehmen, sieht das für J wie ein fester Punkt aus. Wir behandeln dies, indem wir eine Endlosschleife von 1 über und negieren Wenn wir feststellen, dass sie gleich sind, ist dies der-i@=`p@.~:~/
Teil, der ersetztp&|.
.Dieser Zyklus wiederholt sich aufgrund der Verwendung von
i
, bis etwas außerhalb vonsub
Fehlern herauskommt. Soweit mir bekannt ist, kann dies nur passieren, wenn wir keine Charaktere mehr haben oder wenn wir einen unvollständigen Satz von Mustern und Ersetzungen wegwerfen.Wissenswertes über diesen Golf:
;:
kürzer als das manuelle Durchlaufen der Zeichenfolge.0{
sollten die Möglichkeit haben, Fehler zu machen, bevor siesub
in eine Endlosschleife geraten. Dies sollte also funktionieren, wenn das Muster mit der Ersetzung übereinstimmt, aber im Rest der Quelle nie auftaucht. Dies kann jedoch ein nicht angegebenes Verhalten sein oder auch nicht, da ich in den Dokumenten kein Zitat finde. Whoopsie.i
dieser Fehler werden diese jedoch ebenfalls abgefangen. Abhängig davon, wann Sie Strg + C drücken, können Sie:sub
Schleife, indem Sie versuchen, eine Zahl mit einer Zeichenfolge zu verknüpfen, und interpretieren Sie /// dann so, als ob Sie eine Zeichenfolge unendlich oft durch sich selbst ersetzt hätten.sub
Hälfte hinter dir und interpretiere einen halb untergeordneten /// Ausdruck weiter.Anwendungsbeispiel:
quelle
/\\/good/\/
Testfalls. Das Debuggen sagt mir, dass das Problem meine Verwendung ist1!:2&4
, da jqt kein stdin / out hat. Werde untersuchen. Was sind deine9!:12''
und9!:14''
?9!:12''
ist 6 und9!:14''
ist j701 / 2011-01-10 / 11: 25.Perl - 190
Liest das
///
Programm von stdin bis EOF.quelle
m/^(.*?)(?<!\\)\/(.*?)(?<!\\)\/(.*?)(?<!\\)\/(.*)$/s
Art, dass Output, Muster und Austausch gleichzeitig übereinstimmen, zu einem kürzeren Golf führen? Ich kenne selbst kein Perl./a/\0/a
Pip ,
100102 BytesIch hatte noch nie bewiesen, dass Pip Turing-vollständig ist (obwohl es ziemlich offensichtlich ist), und anstatt den üblichen Weg von BF zu gehen, dachte ich, /// wäre interessant. Sobald ich die Lösung gefunden hatte, dachte ich, ich würde Golf spielen und es hier posten.
101 Byte Code, +1 für
-r
Flag:Hier ist meine ungolfed Version mit vielen Kommentaren:
Probieren Sie es online! (Beachten Sie, dass TIO keine Ausgabe ausgibt, wenn das Programm nicht beendet wird. Es gibt auch ein Zeitlimit. Für größere Beispiele und Endlosschleifen wird empfohlen, Pip über die Befehlszeile auszuführen.)
quelle
pip + -r
101 Bytes seinC ++: Visual C ++ 2013 = 423, g ++ 4.9.0 = 442
Das wird nie gewinnen, aber da ich beschlossen habe, dass alle meine zukünftigen Softwareprojekte in dieser großartigen Sprache geschrieben werden, brauchte ich einen Dolmetscher dafür und dachte, ich könnte den, den ich gemacht habe, genauso gut teilen ...
Der Unterschied in der Punktzahl besteht darin, dass Visual C ++ nicht das erste Include benötigt, sondern g ++. Die Punktzahl setzt voraus, dass die Zeilenenden mit 1 gewertet werden.
quelle
if(!o[i]);
alsif(P
speichern Zeichen, oder bin ich Missverständnis , wie #define funktioniert?P
inmain
befindet sich ein Leerzeichen. Sie können also ein Zeichen speichern, indem Sie diese Leerzeichen durch Semikolons ersetzen und aus entfernen#define
. Wenn Sie dann#define
s in anderen verwenden können, können Sie etwas mehr sparen,N(x)
indem Sie(92==P
anstelle vono[i]==92
undO
ebenfalls neu schreiben .N(x)
wieP;else if(n<x)(P==92?
und Ändern AnrufeN
dementsprechend ein paar Bytes könnte speichern.Python 2 (236), Python 3 (198?)
Genannt als
d(r"""/foo/Hello, world!//B\/\\R/foo/B/\R""")
. Die dreifachen Anführungszeichen werden nur benötigt, wenn das///
Programm Zeilenumbrüche enthält. Andernfalls sind einfache Anführungszeichen in Ordnung.BEARBEITEN: Dieser Interpreter druckt nun wie erwartet (zuvor nur ganz am Ende, siehe Kommentare). Entfernen Sie für Python 3 die erste Zeile (ich habe jedoch kein Python 3 in meiner alten Installation, kann also nicht sicher sein, dass es keine andere Änderung gibt).
quelle
/a/ab/bbaa/abb
./a/ab/bbaa/abb
bleibt in einer Endlosschleife stecken, ohne etwas zu drucken, da die erste Ersetzunga
=> istab
. Das richtigea/ab/bbaa/abb
funktioniert wie angekündigt.-u
des Puffers für die Ausgabe zu erzwingen.Cobra - 226
quelle
Rubin ,
119110 BytesBeendet mit Ausnahme
Probieren Sie es online!
Endet sauber (116 Bytes)
Probieren Sie es online!
quelle
Python 2/3 (211 Bytes)
Der folgende Code basiert auf der Antwort von Bruno Le Floch ist kompatibel mit Python 2 und Python 3.
Darüber hinaus riskiert es nicht, die maximale Rekursionstiefe von Python zu erreichen, da es eher iterativ als rekursiv ist.
quelle
in(0,1,2)
nachin 0,1,2
und[""]*2+[1]
nach Golf spielen["","",1]
, was 211 Bytes ergibt .BaCon ,
391387395 BytesVon den Beiträgen auf dieser Seite habe ich nur das Python-Programm zum Laufen gebracht. Die anderen arbeiten für einige /// Samples oder überhaupt nicht. Aus diesem Grund habe ich mich entschlossen, meine Version hinzuzufügen, die eine Implementierung in BASIC ist.
Die Teilnahme an einem CodeGolf-Wettbewerb mit BASIC ist nicht einfach, da BASIC lange Wörter als Anweisungen verwendet. Die einzige in BASIC gebräuchliche Abkürzung ist das '?' Zeichen, was PRINT bedeutet.
Das folgende Programm wird vielleicht nie gewinnen, aber es funktioniert zumindest mit dem gesamten Demo-Code auf dieser Codegolf-Seite und im Esolangs-Wiki . Einschließlich aller Versionen der "99 Flaschen Bier".
quelle