Noch ein Brainfuck-Parsing-Problem, aber diesmal ... anders.
Sie arbeiten in der Firma Infinite Monkeys Incorporated, die Brainfuck-Programme herstellt, um verschiedene interessante Probleme zu lösen (nicht weniger aus Versehen - schließlich erstellt die Firma zufällige Programme). Es scheint jedoch, dass Ihre schnellen Turing-Maschinen, die nur Brainfuck ausführen, ein kleines und teures Problem mit Syntaxfehlern haben - machen Sie eins, und der Computer explodiert. Es ist wahrscheinlich ein Designfehler, aber niemand hatte sich die Mühe gemacht, herauszufinden, warum es passiert.
Da Turing-Maschinen (besonders schnelle) teuer sind (schließlich haben sie unendlich viel RAM, was Kosten verursacht), ist es besser, sicherzustellen, dass das Programm keine Syntaxfehler aufweist, bevor Sie den Code ausführen. In Ihrem Unternehmen wird viel Code ausgeführt, sodass die manuelle Überprüfung nicht funktioniert. Schreiben Sie ein Programm, das den STDIN for Brainfuck-Code liest und mit einem anderen Exit-Status als 0 (Fehler) beendet, wenn das Programm einen Syntaxfehler aufweist (z. B.
]
ein Syntaxfehler, da keine Übereinstimmung vorliegt[
). Beenden Sie mit dem auf 0 gesetzten Beendigungsstatus, wenn das Programm vollständig in Ordnung ist.Vergewissern Sie sich, dass Ihr Programm die Fehler korrekt erkennt
[]
. Sie möchten doch nicht, dass ein anderer Computer explodiert, oder? Oh, und stellen Sie sicher, dass es so kurz wie möglich ist - Ihr Chef bezahlt für kurze Programme (weil er denkt, dass sie schnell sind oder so). Oh, und Sie müssen keinen Code in Brainfuck eingeben (das können Sie auch nicht, da Brainfuck keine Exit-Codes unterstützt) - Ihr Code wird auf einem normalen Computer ausgeführt.
Wie Sie sehen, müssen Sie überprüfen, ob das Brainfuck-Programm "gültig" ist (mit []
Symbolen gepaart ). Beachten Sie, dass Brainfuck-Programme andere Zeichen als []
enthalten können. Verweigern Sie das Programm daher nicht, nur weil es andere Befehle enthält. Kleinster Code gewinnt, aber wahrscheinlich interessieren Sie sich sowieso mehr für Upvotes.
quelle
GCD(a,b)
statt verwenden0 != a || b
.Antworten:
GolfScript, 18 Zeichen
Dieser Code wird erfolgreich mit dem Exit-Code 0 ausgeführt (und gibt einen Teil des Mülls nach stdout aus), wenn die eckigen Klammern in der Eingabe ausgeglichen sind. Wenn dies nicht der Fall ist, schlägt der Vorgang mit einem Exit-Code ungleich Null fehl und es wird eine Fehlermeldung an stderr ausgegeben, z.
oder
Da die Herausforderung nichts über die Ausgabe an stdout / stderr aussagte, schätze ich, dass dies qualifiziert. In jedem Fall können Sie diese jederzeit an umleiten
/dev/null
.Erläuterung:
Der Code entfernt
{[]`?)},
alles außer eckigen Klammern von der Eingabe und~
wertet das Ergebnis als GolfScript-Code aus. Der schwierige Teil ist, dass unausgeglichene Klammern in GolfScript vollkommen legal sind (und in der Tat enthält mein Code eine!), Also brauchen wir eine andere Möglichkeit, um den Code zum Absturz zu bringen.Der Trick, den ich verwende, besteht darin, eine Kopie der Eingabe am unteren Rand des Stapels zu belassen, den gesamten Stapel in einem Array zusammenzufassen (unter Verwendung des Unsymmetrischen
]
) und das erste Element auszuschalten. An diesem Punkt können drei Dinge passieren:[
und versucht wird, ein Element aus einem leeren Array herauszuschieben, stürzt der Interpreter ab (was in diesem Fall genau das ist, was wir wollen!)]
oder nicht geschlossen war[
) handelt es sich um ein Array.Mein ursprünglicher Eintrag mit 14 Zeichen verglich dann den verschobenen Wert mit einer Zeichenfolge, die abstürzen würde, wenn es sich um ein verschachteltes Array handeln würde. Leider hat sich herausgestellt, dass das Vergleichen eines flachen (oder insbesondere leeren) Arrays mit einer Zeichenfolge auch in GolfScript zulässig ist, sodass ich den Kurs ändern musste.
Stattdessen verwendet meine aktuelle Übermittlung eine sehr brachiale Methode, um Arrays von Strings zu unterscheiden: Sie entfernt sie und versucht, das erste Vorkommen von
[
(ASCII-Code 91) zu finden, das genau dann null ist, wenn das nicht ausgewertete nicht vorhanden ist Variable war ein Array. Wenn dies der Fall ist, löst das Teilen der Null mit sich selbst den gewünschten Absturz aus.Ps. Zwei weitere 18-Zeichen-Lösungen sind:
und
Leider habe ich noch keinen kürzeren Weg gefunden, um das "Problem mit leeren Arrays" zu lösen.
quelle
][
(dh scheitert es in Ihrem Programm?)[[]
; Ich habe es jetzt behoben, zum Preis von 4 Zeichen, und es besteht jetzt alle meine Tests.1+
verwandelt ein leeres Array in ein nicht leeres Array, ein nicht leeres Array in ein nicht leeres Array und eine Zeichenfolge in eine Zeichenfolge..{[]`?)},~](n<
. Ich habe es mit deinem versucht1+
, aber es scheint, dass das Array etwas anderes als eine Zahl enthalten muss (vermutlich, damit der Interpreter abstürzt, wenn er versucht, ein Zeichen rekursiv mit einem Array / einer Zeichenfolge zu vergleichen). Das Verwenden vonn+
funktioniert auch nicht, da es das Array zu einer Zeichenfolge zwingt.[n]+
funktioniert , bringt mich aber immer noch auf 18 Zeichen.Brainfuck 76 Bytes
Dies geht verloren, wenn eckige Klammern unsymmetrisch sind und der bf-Interpreter / -Compiler ausfällt. Einige von ihnen haben Exit-Codes, die dies widerspiegeln.
erfordert eof = 0, umschließende Werte und endliche Anzahl von Zellen
In Ubuntu können Sie den Interpreter
bf
(sudo apt-get install bf
) verwendenquelle
Brainfuck
Turing ist ohne E / A abgeschlossen, da Sie ein Programm ausführen können, das alle Berechnungen berechnet und das Ergebnis anzeigt, indem Sie den Arbeitsspeicher nach dem Ausführen überprüfen. BF ohne I / O würde das Interesse der Leute verringern, da es schwierig wäre, Versorgungsunternehmen zu bauen. ZB hätte ich meinen Lisp-Dolmetscher nie machen können .Befunge 98 -
26312019 ZeichenWurde einige massive Bedingungen los. Jetzt arbeitet das Programm wie folgt:
q
Beendet das Programm und zeigt den obersten Wert als Fehlerwert an. Der Fehlerwert ist-11, wenn zu viele vorhanden sind]
, 0, wenn sie ausgeglichen sind, undpositivnegativ, wenn zu viele vorhanden sind[
. Wenn die Zahlpositiv odernegativ ist, werden sovieleAbsolutwerte dieser Zahl]
benötigt, um das Programm auszugleichen.Bearbeiten: Inkrementieren und Dekrementieren umgeschaltet.
[
dient zum Inkrementieren des Zählers und]
zum Dekrementieren des Zählers . Durch Umschalten spare ich 1 Zeichen, da ich für die Ausgangsbedingung nur prüfen muss, ob der Zähler positiv und nicht negativ ist.Alte Version
Dieser Code funktioniert wie folgt:
Edit: erkannte, dass diese akzeptierten Eingaben wie
][
, jetzt endet es, wenn die Zählung negativ wird, mitquelle
[
und]
zu nutzen, um den Vergleich mit beiden zu machen.J (
3835)Erläuterung:
1!:1[3
: lese stdin'[]'=/
: Erstellt eine Matrix, in der die erste Zeile eine Bitmaske des[
s in der Eingabe und die zweite Zeile das]
s ist.1 _1*
: multipliziere die erste mit 1 und die zweite mit -1.+/
: Summiere die Spalten der Matrix und erhalte Delta-Einrückung pro Zeichen+/\
: Erstelle eine laufende Summe von diesen und gib jedem Charakter die Einrückungsstufe({:+.<./)
: Gibt die GCD des letzten Elements ({:
) und des kleinsten Elements (<./
) zurück. Wenn alle Klammern übereinstimmen, sollten beide übereinstimmen,0
damit dies zurückkehrt0
. Wenn die Klammern nicht übereinstimmen, wird ein Wert ungleich Null zurückgegeben.exit
: Stellen Sie den Ausgangswert auf diesen Wert ein und beenden Sie den Vorgang.quelle
Rubin (64)
vorher (68) war es:
Eine andere äquivalente Lösung verwendet
Kann nicht
size
alleine verwendet werden, da dies zu falschen Negativen (!!!) führen würde, wenn die Gesamtzahl der unsymmetrischen Klammern ein Vielfaches von 256 istquelle
=
Operators.0
Dose gehen.Perl, 30 Zeichen
Ihr grundlegender rekursiver Perl-Regex zur Rettung:
Für diejenigen, die mit den hier verwendeten Befehlszeilenargumenten nicht vertraut sind:
-0
Ermöglicht das Festlegen des Zeilenendezeichens für die Zwecke der Dateieingabe; Wird-0
kein Argument verwendet, wird das Zeilenendezeichen auf EOF gesetzt.-n
Liest die Eingabe (in diesem Fall die gesamte Datei) automatisch$_
vorher ein.Wenn der reguläre Ausdruck übereinstimmt, wird ein wahrer Wert zurückgegeben, der für den Exit-Code auf 0 negiert wird. Andernfalls ergibt der falsche Rückgabewert einen Exit-Code von 1.
quelle
bash (tr + sed) - 42
Wenn Ihnen Fehlermeldungen nichts ausmachen, können Sie das letzte Leerzeichen zwischen
`
und entfernen]
, um Länge 41 zu erhalten.quelle
cat
und$()
("[]"
kann auch als geschrieben werden[]
). Ich habe diese Antwort akzeptiert, aber bis ich Verbesserungen in der Länge sehe, werde ich das nicht befürworten, da es zwar kurz ist, aber für die Bash viel kürzer sein könnte.$()
Backticks ersetzt und das gemacht"[]"
->[]
du hast vorgeschlagen.Perl (56 Zeichen)
Die naheliegende Perl-Lösung: ein rekursiver regulärer Ausdruck. Leider ist es ein ziemlich ausführliches Konstrukt.
quelle
Haskell (143)
zu jgon: Die Verwendung von 2 Wachen scheint dichter zu sein als wenn-dann-sonst. Ich glaube auch nicht, dass deine prüft, ob die Klammern in der richtigen Reihenfolge sind ("] [" passt)
quelle
C,
7364 ZeichenDank Vorschlägen von breadbox (obwohl dies wahrscheinlich Little-Endian erfordert, um zu arbeiten):
Wie es funktioniert:
i
wird auf 0 initialisiertc
wird zu einem impliziten int, das wirdargc
(initialisiert auf 1, aber es ist uns egal, solange die höheren Bits nicht gesetzt sind)read(0,&c,1)
Liest ein einzelnes Zeichen in das niedrige Byte von c (bei Little-Endian-Architekturen) und gibt bei EOF 0 zurück.i+1 != 0
es sei denn, das ausgeglichene Klammer-Zitat geht auf -1; Das Multiplizieren funktioniert als (sicherer) Boolescher Wert UND das kostet ein Zeichen weniger als&&
c==91
ergibt 1 für'['
undc==93
ergibt 1 für']'
. (Möglicherweise gibt es einen kleinen Trick, aber mir fällt nichts ein.)return i
Wird mit dem Statuscode 0 beendet, wenn er ausgeglichen ist, und mit einem Wert ungleich Null, wenn dies nicht der Fall ist. Das Zurückgeben von -1 verstößt technisch gegen POSIX, aber das interessiert eigentlich niemanden.Vorherige Version:
quelle
getchar()
anstelle von read verwenden, wird der Code gekürzt und Sie können (implizit)int
anstelle vonchar
für Ihre Variable verwenden. Denken Sie auch daran, dass Globals automatisch auf Null initialisiert werden.c;
definiert ein globales int.][
? Ich bin sicher, es ist nicht ausgeglichen. Müssen Sie nicht mindestens einmal nachverfolgen, ob es negativ wird?Lua, 56
quelle
"^%b[]$"
Was ist das? Können Sie erklären? Das ist doch kein Regex?^
), der ausgeglichenen Menge von[
und]
mit irgendetwas dazwischen (%b[]
) und dem Ende von string ($
) überein .GTB , 55
Vermisst
[]
Verwenden Sie,
0
um anzuhalten.quelle
MATHEMATICA, 88 Zeichen
quelle
s name like
RegularExpressionStringLength
kann ich mit Mathematica niemals Text Code Golf Kontext gewinnen! :)ToCharacterCode
ist viel länger alsord
auch ... PS: Was ist mit einem Exit-Code?Length[StringCases[s,"["|"]"]//.{x___,"[","]",y___}:>{x,y}]
Rubin,
5958Sucht nach öffnender und schließender Klammer, zählt
[
als 1 und]
als -1 und wird beendet, wenn die Anzahl unter 0 fällt.quelle
exit 1
falls Sie danach fragen).Hassium , 104 Bytes
Voll ausgebaut (Anmerkung im Online - Interpreter funktioniert nicht als Eingang () deaktiviert ist) hier
quelle
Turing Machine Code,
286276 BytesAuch hier verwende ich die hier definierte Regeltabellensyntax.
Beendet in state
halt
, um die Eingabe zu akzeptieren undhalt-err
abzulehnen.quelle
halt-err
kann kürzer sein, wiehalt*
zum Beispiel.Pyth, 25 Bytes
Probieren Sie es online!
Python 3 Übersetzung:quelle
Haskell (
167, 159)Habe das hauptsächlich zum Spaß gemacht, wenn jemand Vorschläge hat, wie man es kürzer macht, würde ich mich freuen, wenn ich sie höre :)
Bearbeiten: Es wurde ein Problem behoben, auf das ich in den Kommentaren hingewiesen wurde (11 Byte hinzugefügt).
Bearbeiten 2: Zusatzfunktion zum Testen von Prädikaten mit von user13350 inspirierten Guards erstellt, wobei 8 Bytes entfernt wurden.
quelle
][
SchlägtStax ,
1411 ZeichenFühren Sie es aus und debuggen Sie es
Gutschrift auf @recursive für -3 Bytes.
ASCII-Äquivalent:
Entfernen Sie alle Zeichen außer
[]
und dann,[]
bis sich die Zeichenfolge nicht mehr ändert. Rückgabe,1
wenn die letzte Zeichenfolge leer ist.quelle
.[]|&
die Zeichen filtern und dann das Literal für 11