Schreiben Sie ein Programm, das eine Zeichenfolge aus vier Zeichen enthält ()[]
, die diese Punkte erfüllt:
- Jede linke Klammer
(
hat eine passende rechte Klammer)
. - Jede linke Klammer
[
hat eine passende rechte Klammer]
. - Übereinstimmende Paare von Klammern und Klammern überlappen sich nicht. zB
[(])
ist ungültig, weil die passenden Klammern nicht vollständig in den passenden Klammern enthalten sind und umgekehrt. - Das erste und das letzte Zeichen sind übereinstimmende Klammernpaare. Also
([]([]))
und[[]([])]
gültig ist das aber[]([])
nicht.
(Eine Grammatik für das Eingabeformat ist <input> ::= [<input>*] | (<input>*)
.)
Jedes Paar übereinstimmender Klammern und Klammern ergibt eine nicht negative ganze Zahl:
- Die Werte von Paaren in übereinstimmenden Klammern werden alle summiert . Das leere Match
()
hat Wert0
. - Die Werte von Paaren in übereinstimmenden Klammern werden alle multipliziert . Das leere Match
[]
hat Wert1
.
(Die Summe oder das Produkt einer Zahl ist dieselbe Zahl.)
Beispielsweise ([](())([][])[()][([[][]][][])([][])])
kann aufgeschlüsselt und ausgewertet werden als 9
:
([](())([][])[()][([[][]][][])([][])]) <input>
(1 (0 )(1 1 )[0 ][([1 1 ]1 1 )(1 1 )]) <handle empty matches>
(1 0 2 0 [(1 1 1 )2 ]) <next level of matches>
(1 0 2 0 [3 2 ]) <and the next>
(1 0 2 0 6 ) <and the next>
9 <final value to output>
Ein anderes Beispiel:
[([][][][][])([][][])([][][])(((((([][]))))))] <input>
[(1 1 1 1 1 )(1 1 1 )(1 1 1 )((((((1 1 ))))))]
[5 3 3 (((((2 )))))]
[5 3 3 ((((2 ))))]
[5 3 3 (((2 )))]
[5 3 3 ((2 ))]
[5 3 3 (2 )]
[5 3 3 2 ]
90 <output>
Ihr Programm muss die ganze Zahl auswerten und drucken, die durch die gesamte Eingabezeichenfolge dargestellt wird. Sie können davon ausgehen, dass die Eingabe gültig ist. Der kürzeste Code in Bytes gewinnt.
Anstelle eines Programms können Sie auch eine Funktion schreiben, die eine Zeichenfolge aufnimmt und die Ganzzahl ausgibt oder zurückgibt.
quelle
Antworten:
CJam, 23
Mit GROSSEN Credits an Dennis! Probieren Sie es online aus
Erläuterung:
Das Programm konvertiert die Eingabe in einen CJam-Ausdruck und wertet ihn dann aus.
[…]
wird[…1]:*
(1 anhängen und multiplizieren)(…)
wird[…0]:+
(0 anhängen und addieren)quelle
q"])(""1]:*0]:+["4/ers~
Common Lisp - 98
(
durch(+
[
durch(*
]
durch)
Dazu muss die
cl-ppcre
Bibliothek in das aktuelle Lisp-Bild geladen werden.Erläuterung
Funktionen
*
und+
sind variabel und geben ihren neutralen Wert zurück, wenn keine Argumente angegeben werden. Für Ihre Beispiele sind die ausgewerteten Lisp-Formulare die folgenden:und
Ohne reguläre Ausdrücke - 183 Bytes
Komm schon, Lisp - 16 Bytes (experimentell)
Andere Sprachen sind so knapp, dass ich versucht bin, meine eigene Golfsprache basierend auf Common Lisp für kürzere Saitenmanipulationen zu entwickeln. Derzeit gibt es keine Spezifikation und die Bewertungsfunktion ist die folgende:
Tests:
s
und zwei Stapelp
undq
.p
.<
: knallt abp
und drückt aufq
.r
: Ersetzt ins
(muss ein String sein) von Zeichen inq
bis Zeichen inp
; Ergebnis wird gespeichert ins
;p
undq
werden geleert.R
: Aus String lesens
, Ergebnis in Variable speicherns
.E
: Auswertungsforms
, Ergebnis speichern ins
.quelle
Pyth,
353433 BytesDemonstration.
1 Byte danke an @Jakube.
Wir beginnen mit der Analyse der Eingabe. Das Eingabeformat ist ähnlich wie bei Python, aber nicht ganz. Wir brauchen Kommas nach jeder Gruppe in Klammern oder Klammern. Das Komma am Ende einer Gruppe in Klammern ist unnötig, aber harmlos. Um dies zu erreichen, verwenden wir diesen Code:
,
Am Ende der Zeichenfolge verbleibt ein Extra , das das gesamte Objekt in ein Tupel einwickelt. Dies ist jedoch harmlos, da das Tupel summiert wird und daher einen Wert aufweist, der dem Element entspricht.Nachdem die Zeichenfolge analysiert wurde, müssen wir ihren Wert finden. Dies geschieht mit einer benutzerdefinierten Funktion
y
, die für das analysierte Objekt aufgerufen wird. Die Funktion ist wie folgt definiert:quelle
Emacs lisp, 94
Das Format sieht sehr lispy aus, daher dachte ich, dass eine einfache Transformation funktionieren könnte:
Das Zwischenformat sieht ungefähr so aus (für das Beispiel in der Frage):
Wir werden durch die Tatsache unterstützt, dass Addition und Multiplikation bereits mit einer leeren Argumentliste das tun, was wir wollen.
Entgolft und interaktiv für Ihr Spielvergnügen:
quelle
interactive
(anstelle von Buffer-String Read-from-String verwenden).Netzhaut , 111 Bytes
Gibt eine unäre Ausgabe aus.
Jede Zeile sollte in eine eigene Datei gehen, aber Sie können den Code als eine Datei mit dem
-s
Flag ausführen . Z.B:Erklärung kommt später.
quelle
Java, 349 Zeichen
Ein einfacher rekursiver Ansatz. Erwartet, dass der String das erste Argument ist, mit dem das Programm aufgerufen wird.
Erweitert:
quelle
Perl 5, 108
Als Dolmetscher gemacht, statt neu zu schreiben und zu bewerten. Keine großartige Show, aber es macht trotzdem Spaß zu schreiben.
Nicht golfen:
quelle
Python, 99
Ich habe verschiedene Methoden ausprobiert, aber die kürzeste, die ich bekommen konnte, war im Grunde nur ein Ersatz und eine Bewertung. Ich war angenehm überrascht, als ich feststellte, dass ich alle abschließenden Zeichen belassen konnte
,
, da Python analysieren kann[1,2,]
und das letzte abschließende Komma nur das Ganze in ein Tupel setzt. Die einzige andere nicht einfach Teil wäre dasord(c)%31%7
die verschiedenen Charaktere zu trennen out (es ausgewertet2
,3
,1
,0
für(
,)
,[
,]
respectively)quelle
Java, 301
Ein etwas anderer Ansatz als die Antwort von TheNumberOne, obwohl meine auch rekursiver Natur ist. Die Eingabe erfolgt über die Befehlszeile. Die Methode void spart einige Bytes, wenn die nicht mehr benötigten Zeichen entfernt werden.
erweitert:
quelle
Python,
117110109 BytesEin Aspekt, mit dem ich zu kämpfen hatte, ist, dass die Funktion im Grunde zwei Rückgabewerte hat: das Produkt / die Summe und die neue Position in der Zeichenfolge. Ich benötige jedoch eine Funktion, die nur das Ergebnis zurückgibt, sodass das Zurückgeben eines Tupels nicht funktioniert. Diese Version verwendet ein "Referenz" -Argument (Liste mit einem Element), um die Position von der Funktion zurückzugeben.
Ich habe eine kürzere Version (103 Bytes), die eine globale Variable für die Position verwendet. Das funktioniert aber nur beim ersten Anruf. Und eine Funktion, die nur einmal funktioniert, scheint ein bisschen faul zu sein. Ich bin mir nicht sicher, ob es für Code-Golf akzeptabel wäre.
Der Algorithmus ist eine einfache Rekursion. Ich habe eine Reihe von Variationen für den Ausdruck ausprobiert, der das Produkt / die Summe aktualisiert. Ich hatte ein paar Versionen, die genau gleich lang waren, aber keine kürzer.
Ich habe irgendwie erwartet, dass der Ansatz, der daraus einen Ausdruck macht, der bewertet wird, wahrscheinlich gewinnen wird. Aber wie sie sagen: "Iterieren ist menschlich, göttlich wiederverwenden."
quelle
Clojure - 66 Bytes
Beachten Sie, dass
([] (()) ([] []) [()] [([[] []] [] []) ([] [])])
es sich um ein gültiges Clojure-Formular handelt. So:g
.g
Funktion gilt+
oder*
für das Ergebnis des Aufrufs vong
Unterelementen ihrer Argumente.x
in einer leeren Sequenz erreicht;(map g x)
zurückkehrtnil
, undapply
den neutralen Wert für den Betrieb zurückkehrt.quelle
JavaScript (ES6), 116 Byte
quelle