Der dritte Flak!

19

Diese Challenge wurde im Rahmen der LotM-Challenge im April 2018 veröffentlicht


Brain-Flak ist eine Turing-Tarpit-Sprache, die hier bei PPCG viel Ruhm erlangt hat. Die Erinnerung an die Sprache besteht aus zwei Stapeln, aber ein "versteckter" dritter Stapel wurde entdeckt von Wh e at Wizard entdeckt , was zu einigen interessanten neuen Denkweisen für Brain-Flak-Programme führte.

Wie wäre es also damit, diesem armen, versteckten dritten Stapel mehr Sichtbarkeit zu verleihen? Lassen Sie uns eine Sprache erstellen, in der der dritte Stapel die Anerkennung erhält, die er verdient! Hier präsentiere ich euch Third-Flak .

Die Sprache

In Third-Flak gibt es nur einen Stapel, den dritten Stapel. Die Betreiber arbeiten auf dem dritten Stapel in der gleichen Art , wie sie in Brain-Flak, aber hier gibt es keine [],{} , <>nilads und keine {...}Monade (so die einzigen zulässigen Zeichen in einem Third-Flak - Programm sind ()[]<>). Hier ist, was jeder Operator tut (Beispiele werden gegeben, die den dritten Stapel mit einer Liste darstellen, in der das letzte Element die Oberseite des Stapels ist):

  • ()ist der einzige zweistellige Operator in Third-Flak. Es erhöht die Oberseite des dritten Stapel von 1. Beispiel: [1,2,3][1,2,4]

  • (, [, <: Alle Öffnungs Klammern , die nicht von dem vorherigen Fall Push a abgedeckt sind0 zu dem dritten Stapel. Beispiel: [1,2,3][1,2,3,0]

  • )Knackt zwei Elemente aus dem dritten Stapel und drückt ihre Summe zurück. Beispiel:[1,2,3][1,5]

  • ]Fügt zwei Elemente aus dem dritten Stapel hinzu und schiebt das Ergebnis des Subtrahierens des ersten von dem zweiten zurück. Beispiel: [1,2,3][1,-1]

  • >Öffnet ein Element aus dem dritten Stapel. Beispiel [1,2,3][1,2]

Und hier sind die anderen Regeln der Sprache:

  • Zu Beginn der Ausführung enthält der dritte Stapel nur eine einzige 0.

  • Es ist verboten, leer zu haben []oder<> innerhalb eines Programms (sie wären sowieso Noops, wenn sie der Semantik von Third-Flak folgen, aber sie haben tatsächlich eine andere Bedeutung in Brain-Flak, die hier nicht wiederhergestellt werden kann).

  • Klammern müssen immer ausgeglichen sein, mit Ausnahme der Tatsache, dass abschließende Klammern am Ende des Programms fehlen können. Als Beispiel [()<(()ist ein gültiges Third-Flak-Programm (und der dritte Stack am Ende des Programms wäre[1,0,1] ).

  • Ein Programm kann nur die sechs zulässigen Zeichen enthalten ()[]<> . Programme dürfen garantiert nicht leer sein.

Hinweis: Die vorherigen Regeln implizieren, dass Sie sich nicht mit Situationen befassen müssen, in denen Sie von einem leeren Stapel abspringen müssen.

Die Herausforderung

Einfach, schreibe einen Interpreter für Third-Flak. Ihr Programm muss als Eingabe ein Third-Flak-Programm annehmen und als Ausgabe den Status des dritten Stapels am Ende des Programms zurückgeben.

Ihr Ausgabeformat ist flexibel, solange es möglich ist, den Status des dritten Stapels eindeutig auszulesen und die gleiche Nummer immer auf die gleiche Weise zu codieren zu versuchen zu betrügen ist in Ordnung).

Ihre Ausgabewahl kann den Bereich der Nummern einschränken, die Sie verwalten können, solange dies die Herausforderung nicht trivialisiert (da dies der Fall wäre) eine Standardlücke ).

Testfälle

Für jeden Testfall ist die erste Zeile die Eingabe und die zweite Zeile der Ausgabestapel, der als durch Leerzeichen getrennte Liste von Zahlen dargestellt wird, wobei die Oberseite des Stapels das letzte Element ist.

[()<(()
0 1 0 1

[((((()()()()()))
0 0 0 5

((([()][()][()])))
-3

[<<(((()()()())(((((
0 0 0 0 0 4 0 0 0 0 0

[()]<(([()])><[()]
-1 0 -1

(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(())(())(()())(())(())(())(()())(()()()())(())(()()()()())(()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(())(())(()())(())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(())(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(()()())(())(()()())(())(())(())(()())(()()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(())(())(())(()()())(())(())(())(()())(())(()())(()()()())(())(())(()()()()())(()())(()())(())(()()())(())(())(())(())(()()())(()())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(()()()()())(())(()()())(())(())(()())(())(()()()()())(())(()()()()())(())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(())(()()()()())(())(())(())(()())(())(()()()()())(())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()()()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(())(()())(()()()())(())(())(()())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(()()())(())(())(()())(())(())(()()()()())(()()()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(()()()())(()()()())(()()
718 2
Löwe
quelle
Ist der Stack mit einer 0 initialisiert? Ansonsten [()]verstößt es gegen die Regel, dass wir uns nicht darum kümmern müssen, von einem leeren Stapel zu springen
Jo King,
1
@JoKing Yep: "Zu Beginn der Ausführung enthält der dritte Stapel nur eine einzige 0". Vielleicht sollte ich diesen Teil etwas hervorheben, ich hatte Angst, dass es zu leicht gewesen wäre, ihn zu übersehen.
Leo
Hoppla, ich weiß nicht, wie ich das verpasst habe
Jo King
7
Durchgestrichen e ist immer noch e.
Weizen-Assistent
2
Wenn jemand nicht sehen kann, die durchgestrichen eist hier .
User202729

Antworten:

21

Brain-Flak , 276 Bytes

{({}<>)<>}<>{(((()()()()()){})((({}){})())(({})({}{}([{}])(<>))))((()()(){[()]<{}>}{}){()<{{}}>}{}<<>({}({})())>{()(<{}>)}{}<>)<>}<>{(([{}]()<>)){{}({}())((){[()](<({}())((){[()](<({}())((){[()](<{}([{}]{})>)}{}){(<{}{}>)}{}>)}{}){(<{}({}{})>)}{}>)}{}){(<{}{}({}())>)}}{}<>}<>

Probieren Sie es online!

Sie mussten wissen, dass dies kommen würde.

Nitrodon
quelle
4

Retina 0.8.2 , 64 48 46 Bytes

\(\)
_
[([<]
¶
+1`¶(.*)\)|(.*)¶\2]|¶.*>
$1
%`_

Probieren Sie es online! Gibt den Stapel von unten nach oben aus. Funktioniert nur mit nicht negativen ganzen Zahlen, und der letzte Testfall ist zu langsam, sodass der Link nur drei Testfälle enthält. Erläuterung: Der Stapel steht implizit vor dem Programm, daher beginnt er als leere Zeichenfolge, die eine einzelne Null darstellt. Der Nullpunkt wird in einen verwandelt, der zum unären Zählen verwendet wird, während die anderen offenen Klammern in Zeilenumbrüche umgewandelt werden, die eine Null auf den Stapel aufschieben, wenn sie angetroffen werden. Die geschlossenen Klammern werden dann einzeln verarbeitet, damit der Stapel korrekt ist. Daslöscht nur das oberste Element. Schließlich wird der Stapel in eine Dezimalzahl konvertiert. Bearbeiten: 2 Bytes dank @Leo gespeichert.()_) löscht die vorherige Zeile, fügt die beiden obersten Elemente zusammen, der ]löscht das oberste Element und gleicht es mit dem vorherigen Element auf dem Stapel ab, wodurch es subtrahiert wird>

Neil
quelle
Wofür ist das $3? (Gute Antwort, trotzdem!)
Leo
@Leo Das ist ein Überbleibsel von einem früheren Golf. Danke, dass du es gesehen hast!
Neil
4

Python 3 , 145 144 132 122 116 109 104 Bytes

-7 Bytes dank Leo!

Und - 5 danke an Lynn!

s=[0]
for i in input().replace('()',' '):s+=i in']>) 'and(i<'!'or(2-ord(i)%5)*s.pop())+s.pop(),
print(s)

Probieren Sie es online!

Ziemlich Standardimplementierung.Aber jetzt nicht so lesbar. Ich bin enttäuscht, dass ich keinen kürzeren Weg finden konnte, um zwischen Anfangs- und Endklammer zu prüfen.

Einige Einzeiler-Versuche:

  • 124 Bytes (anonyme Funktion):

    lambda c:[s.append(i in']>) 'and(i<'!'or~-']>)'.index(i)*s.pop())+s.pop())or s for s in[[0]]for i in c.replace('()',' ')][0]
  • 115 Bytes (volles Programm):

    s=[0];[s.append(i in']>) 'and(i<'!'or~-']>)'.index(i)*s.pop())+s.pop())for i in input().replace('()',' ')];print(s)

Append ist ärgerlich länger als normale Zuweisung

Scherzen
quelle
~-']>)'.index(i)kann sein (2-ord(i)%5), 4 Bytes zu sparen.
Lynn
2

Ruby , 98 91 Bytes

->s{a=[i=0];s.chars{|c|a<<("([<"[c]?s[i,2]["()"]?1:0:a.pop*~-"]>)".index(c)+a.pop);i+=1};a}

Probieren Sie es online!

Mein anfänglicher Code funktionierte im Geiste ähnlich wie Jo Kings Python-Antwort, sodass wir vor dem Durchlaufen der Quell-Zeichen alle ersetzten () Teilzeichenfolgen durch ein anderes Zeichen als eindeutigen Operator .

Zumindest in Ruby stellte sich jedoch heraus, dass Golfer dies nicht tun, sondern sich eher für eine etwas umständlichere Herangehensweise entscheiden. Hier pflegen wir einen zusätzlichen Indexeri , der unsere Position in der Quellzeichenfolge verfolgt, und wann immer eine öffnende Klammer angetroffen wird, prüfen wir im Voraus, ob unsere aktuellen + nächsten Zeichen s[i,2]den ()Operator bilden. In diesem Fall legen wir 1 anstelle von 0 auf den Stapel und lassen das Schließen )im nächsten Schritt seinen Job erledigen.

Kirill L.
quelle
1

05AB1E , 25 Bytes

΄()1:v"0+0\0->"žuykè.V})

Probieren Sie es online!

Erläuterung

Î                           # initialize the stack with 0 and the input
 „()1:                      # replace any occurrence of "()" in the input with 1
      v                }    # for each char y in this string
                žuyk        # get its index in the string "()[]<>{}"
       "0+0\0->"    è       # use this to index into the string "0+0\0->"
                     .V     # eval
                        )   # wrap the stack in a list
Emigna
quelle
1

R , 182 177 Bytes

function(P){for(k in utf8ToInt(gsub("\\(\\)",7,P))%%8){if(k%in%0:4)F=c(0,F)
if(k==7)F[1]=F[1]+1
if(k==1)F=c(F[2]+F[3],F[-3:0])
if(k==5)F=c(F[2]-F[1],F[-2:0])
if(k==6)F=F[-1]}
F}

Probieren Sie es online!

Gibt den Stapel zurück, wobei der obere Teil des Stapels der erste und der untere Teil des Stapels der letzte ist.

Tauscht ()mit 7und berechnet dann die Codepunkte Mod 8, um eindeutige numerische Werte zu erhalten, mit denen einfacher und besser gearbeitet werden kann als mit Zeichenfolgen.

Es ist besser, mit dem Anfang eines Vektors in R zu arbeiten, also konstruieren wir den Stapel auf diese Weise.

Dann sieht es ein ), oder wenn k==1es eine zusätzliche Null an der Spitze des Stapels hinzufügt, da es Golfspieler ist, es hinzuzufügen und zu entfernen.

Giuseppe
quelle
1

CJam , 29 Bytes

0q")]>([<""+-;U"er"U+"/')*~]p

Probieren Sie es online!

0q                              Push 0, input
  ")]>([<""+-;U"er              Translate )]>([< to +-;UUU
                  "U+"/')*      Replace U+ by )
                          ~     Eval as CJam code
                           ]p   Wrap and pretty-print stack
Lynn
quelle
1

Ceylon, 285 266 Bytes

function f(variable String c){variable Integer[]s=[0];value o=>[s[0]else nothing,s=s.rest][0];void u(Integer i)=>s=[i,*s];while(c!=""){if(c[0:2]=="()"){u(1);c=c.rest;}switch(c[0])case(')'){u(o+o);}case(']'){u(-o+o);}case('>'){noop(o);}else{u(0);}c=c.rest;}return s;}

Probieren Sie es online!

(19 Byte aufgrund eines Vorschlags von Leo gespeichert.)

Formatiert und kommentiert:

// Interpreter for ThirdFlak
// Question:    /codegolf//q/163242/2338
// This answer: /codegolf//a/163403/2338
//
// This function takes the code as a string, and returns the value
// of the stack as a sequence of Integers.
function f(variable String c) {
    // stack, in the beginning just a single 0.
    // Top element of the stack is the first, because push + pop is easier this way.
    variable Integer[] s = [0];
    // pop – used like an Integer variable (not a function – this saves the `()`), but has side effects.
    value o =>
        // `s[0]` is the first element of the stack. We tell the compiler
        // that it is non-null (otherwise we'll get an error at run time)
        // using the `else nothing`. `s.rest` is `s` without its first element.
        // Both together are wrapped into a 2-tuple, of which we then take just
        // the first element, to have both together in an expression instead
        // the longer way using an accessor block with a temporary variable and a return.
        // value o {
        //   value r = s[0] else nothing;
        //   s = s.rest;
        //   return r;
        // }
        [s[0] else nothing, s = s.rest][0];
    // push
    void u(Integer i) =>
        // a tuple enumeration, using the spread argument.
        s = [i, *s];
    // the main loop
    while (c != "") {
        if (c[0:2] == "()") {
            // »`()` is the only two-characters operator in Third-Flak. It increases the top of the third stack by 1.«
            // As `)` alone adds the two top elements together, we can just push a one here, and let the handling for `)` do the rest.
            u(1);
            c = c.rest;
        }
        switch (c[0])
        case (')') {
            // »`)` pops two elements from the third stack and pushes back their sum.«
            u(o + o);
        }
        case (']') {
            // »`]` pops two elements from the third stack and pushes back the result of subtracting the first from the second.«
            // As the o written first is the first one, we can't write this as a subtraction.
            u(-o + o);
        }
        case ('>') {
            // »`>` pops an element from the third stack.«
            // `o;` alone is not a valid statement, so we pass it to the `noop` function.
            noop(o);
        }
        else {
            // all other valid code characters are `(`, `[`, `<`, which all just push a 0.
            u(0);
        }
        c = c.rest;
    }
    return s;
}

Probieren Sie es online!

Paŭlo Ebermann
quelle
Ich kenne Ceylon nicht wirklich, aber vielleicht könntest du das erste Gehäuse des Schalters entfernen und den else-Teil verwenden, um alle öffnenden Klammern zu verwalten :)
Leo
Hmm, ich denke das könnte funktionieren ... es würde das Verhalten für ungültige Eingaben ändern, aber das ist kein Problem.
Paŭlo Ebermann