BrainFlow Interpreter!

11

BrainFlow

Was ist BrainFlow?

BrainFlow ist eine Erweiterung von BrainF ** k (BFk) mit 3 zusätzlichen Befehlen für zusätzliche Funktionalität und Verwirrung.

Welche Befehle?

Zusätzlich zu den normalen BFk-Befehlen haben wir auch:

^ Springt abhängig vom Wert in der Zelle zur Zelle #. Beispiel: Wenn wir uns in Zelle 0 mit einem Wert von 4 befinden, springt uns ^ zu Zelle 4.

= Setzt den Wert in der Zelle auf den Index der Zelle. Beispiel: Wenn wir uns in Zelle 4 mit dem Wert 0 befinden, setzt = unseren Wert auf 4.

& Setzt den Wert in der aktuellen Zelle gleich dem Wert in der Zelle basierend auf dem Wert in unserer aktuellen Zelle. (Dies ist schwer zu sagen, daher hier ein Beispiel!) Beispiel: Wir befinden uns in Zelle Nr. 33 und unser aktueller Wert in dieser Zelle ist 7 und setzen unseren aktuellen Wert in Zelle Nr. 33 auf den Wert in Zelle Nr. 7.

Optionale Herausforderungen

Wenn Sie eine der folgenden Aufgaben ausführen, wird der angegebene Bonus auf Ihre Byteanzahl angewendet.

Interpreter written in BrainFlow (Kann von der Stichprobe interpretiert werden und enthält mindestens ein aussagekräftiges ^ = oder &): Punktzahl / 3

Interpreter written in BrainF**k: Punktzahl / 2

Doesn't contain any English letters (in either upper or lower case): Punktzahl - 20

Doesn't contain any of the BrainFlow / BFk commands in the interpreter itself: Punktzahl - 50

Beispiel

Ein Beispiel für einen Java-Interpreter:

import java.util.Scanner;

public class Interpreter {

    private String exp;

    private int[] values = new int[256];
    private int index = 0;

    private Scanner in;

    public Interpreter(String exp, Scanner in){
        this.exp = exp;
        this.in = in;
    }

    public void run(){
        //Reset index and values
        for(int i = 0; i < values.length; i++){
            values[i] = 0;
        }
        this.index = 0;

        System.out.println("Starting...");
        this.process(this.exp, false);
        System.out.println("\nDone.");
    }

    private void process(String str, boolean loop){
        boolean running = loop;
        do{
            for(int i = 0; i < str.length(); i++){
                switch(str.charAt(i)){
                case '>':increaseIndex();break;
                case '<':decreaseIndex();break;
                case '+':increaseValue();break;
                case '-':decreaseValue();break;
                case '[':
                    String s = str.substring(i);
                    int j = this.getClosingIndex(s);
                    if(this.values[this.index] == 0){
                        i +=j;
                        break;
                    }
                    process(s.substring(1, j), true);
                    i += j;
                    break;
                case '.':
                    int v = this.values[this.index];
                    System.out.print((char)v);
                    break;
                case ',':this.values[this.index] =  this.in.next().charAt(0);break;
                case '^':this.index = this.values[this.index];break;// Jumps to the index specified in the current cell.
                case '=':this.values[index] = this.index;break;// Sets the value at cell #x to x
                case '&':this.values[index] = this.values[this.values[index]];break;// If cell contains X, makes value of current cell equal to value in cell X
                default:
                    //Ignore others
                    break;
                }
            }
            if(this.values[this.index] == 0){
                running = false;
            }
        }while(running);
    }

    private void increaseIndex(){
        if(++this.index >= this.values.length){
            this.index = 0;
        }
    }

    private void decreaseIndex(){
        if(--this.index < 0){
            this.index = this.values.length - 1;
        }
    }

    private void increaseValue(){
        int newVal = this.values[this.index] + 1;
        if(newVal >= this.values.length){
            newVal = 0;
        }
        this.values[this.index] =  newVal;
    }

    private void decreaseValue(){
        int newVal = this.values[this.index] - 1;
        if(newVal < 0){
            newVal = this.values.length - 1;
        }
        this.values[this.index] =  newVal;
    }

    private int getClosingIndex(String str){
        int openings = 0;
        int closings = 0;
        for(int i = 0; i < str.length(); i++){
            char c = str.charAt(i);
            if(c == '['){
                openings++;
            }else if(c == ']'){
                closings++;
            }
            if(openings == closings){
                return i;
            }
        }
        return -1;
    }
}

Nicht einmal in der Nähe von Golf, sollte aber einen guten Ausgangspunkt bieten.

Die niedrigste Endpunktzahl gewinnt, wobei die Punktzahl die Anzahl der Bytes in Ihrem Programm ist, nachdem die entsprechenden Herausforderungsreduzierungen berücksichtigt wurden.

Testen

Das folgende BrainFlow-Programm sollte die angegebene Ausgabe drucken, nachdem ein '+' - Zeichen von stdin gelesen wurde:

<<,++++[>++++[>++++<-]<-] Set cell #0 to a value dependent on input
>>>+[[-]&>=]+& Set every other cell to that value
[ Start loop
+^ Add one to current value and jump to that cell index
. Print the value at that cell
& Copy value from specified cell
] End loop

Ausgabe:

ðñðòñðòðôóòñóñôóðòõóñõðôôóòñööõôöðóöðõðùõñô÷ùõóñöóùñô÷øôøõôòöõóðòöóñ÷ðõôûôòú÷úø÷öùøöùñøðùúðûðþöûñùýøðòñ
Spocot
quelle
Beachten Sie, dass Sie mit & im Wesentlichen Variablen in den unteren Zellen erstellen und später darauf verweisen können. Wenn ich beispielsweise mein Alter in der 2. Zelle und den Monat, in dem ich in der 3. Zelle geboren wurde, speichere und mich derzeit in der 64. Zelle befinde, kann ich ++&mein Alter +++&abrufen oder den Monat abrufen, in dem ich geboren wurde Natürlich hat die 64. Zelle den Standardwert 0)
Spocot
2
Ich denke, Sie meinen "Obermenge", nicht Teilmenge.
28ıʇǝɥʇuʎs
@ ɐɔıʇǝɥʇuʎs Geändert von subsetzu extension. Danke für die Rückmeldung.
Spocot
Die Punktzahl für das Schreiben in Brainflow ist eine schlechte Idee - Brainfuck ist eine Teilmenge von Brainflow, daher ist jedes Brainfuck-Programm ein Brainflow-Programm. Es ist so, als würde man sagen, dass ein C ++ - Programm besser abschneidet als ein C-Programm. OK, mein C-Programm ist ein C ++ - Programm, soo ....
Pseudonym117
1
Warum hat das Schreiben einer Implementierung in Brainfuck einen geringeren Vorteil als das Schreiben einer Implementierung in Brainflow? Ersteres scheint eine größere Herausforderung zu sein, da es sich um eine kleinere Sprache handelt.
Peter Olson

Antworten:

7

Perl - 233 230 210 182 180 176 174 171 Bytes

$/=$,;%d=qw(> $p++ < $p-- + $v[$p]++ - $v[$p]-- , $v[$p]=ord+getc . print+chr+$v[$p] [ while+$v[$p]{ ] } ^ $p=$v[$p] = $v[$p]=$p & $v[$p]=$v[$v[$p]]);eval$d{$_}for<>=~/./g

Nehmen Sie einfach einen vorhandenen BrainFuck-Interpreter von mir, spielen Sie Golf und fügen Sie die BrainFlow-Funktionen hinzu.

Update: Das Programm wurde vollständig umstrukturiert, um 28 Bytes zu verlieren.

malkaroee
quelle
Beachten Sie, dass Sie ungültige Werte erhalten würden, wenn Sie eine Zeichenfolge von 300 "+" erhalten würden. Nach / während Sie viele dieser Werte festlegen, müssen Sie eine% 256-Überprüfung durchführen.
user0721090601
Ich denke, das funktioniert nicht mit Schleifen ( []). Sie können dafür nicht Zeichen für Zeichen bewerten.
Nutki
Wie werden die Pluspunkte wieder in Klammern übersetzt?
Nutki
6

Lassen Sie uns diese Party beginnen.

C - 408 384 393 390 380 357 352 Bytes (immer noch weghackend)

Kompilieren Sie mit gccauf einem POSIX-kompatiblen System. Das erste Argument ist der Name einer Datei, die den zu interpretierenden Brainflow-Code enthält. Zeilenumbrüche hinzugefügt, um die Lesbarkeit zu verbessern.

i,p,b[9999],*k=b;unsigned char g[9999],a[30000],*d=a;main(c,v)char**v;
{read(open(v[1],0),g,9999);while(c=g[i++]){c-62||d++;c-60||d--;c-43||
(*d)++;c-45||(*d)--;c-46||putchar(*d);c==44?*d=getchar():0;c==94?d=a+*d:0;
c==61?*d=d-a:0;c==38?*d=a[*d]:0;c==93?i=*(--k):0;if(c==91)if(*d)*k++=i-1;else 
while(c=g[i++]){c==91?p++:0;if(c==93)if(p)p--;else break;}}}

Und die ungolfed Version, wenn Sie interessiert sind. Lassen Sie mich wissen, wenn Sie Fehler sehen.

int i, depth, buffer[9999], *stack = buffer;
unsigned char c, program[9999], array[30000], *data = array;

main(int argc, char **argv)
{
    read(open(argv[1], 0), program, 9999);

    while(c = program[i++]){
        if (c=='>') data++;
        if (c=='<') data--;
        if (c=='+') (*data)++;
        if (c=='-') (*data)--;
        if (c=='.') putchar(*data);
        if (c==',') *data=getchar();
        if (c=='^') data=array+*data;
        if (c=='=') *data=data-array;
        if (c=='&') *data=array[*data];
        if (c==']') i=*(--stack);
        if (c=='[')
            if (*data) *stack++=i-1;
            else while (c=program[i++]) {
                    if (c=='[') depth++;
                    if (c==']') if (depth) depth--; else break;
            }
    }
}

Aktualisierung:

  • Vielen Dank für das erste Feedback, das es mir ermöglicht hat, zusätzliche 24 Bytes zu sparen.

  • Zeichenfehler behoben. Weitere 9 Bytes hinzugefügt.

  • Weitere 3 Bytes pro Vorschlag von es1024 wurden gespeichert.

  • Weitere 10 Bytes pro weiteren Vorschlägen von es1024 wurden gespeichert.

  • Ich habe gerade daran gedacht, dass globale Variablen auf 0 initialisiert werden. Von fread und fopen auf read und open umgeschaltet. 23 Bytes gespeichert.

  • Sie müssen im Programm keinen Nullterminator setzen, da der Puffer bereits auf Null initialisiert ist. 5 Bytes gespeichert.
Oder von
quelle
2
Ich denke das if () und das; könnte durch?: ersetzt werden und einige Zeichen speichern.
Jerry Jeremiah
2
Die Zeichenliterale können durch ihre ASCII-Entsprechungen ersetzt werden, um Zeichen zu speichern.
Pseudonym117
1
@Orby Es scheint, dass Eingabezeichen nicht richtig verarbeitet werden. Es sollte sie in die ASCII-Darstellung konvertieren und speichern. Davon abgesehen funktioniert es.
Spocot
1
Sie können ersetzen main(int c,char**v){mit main(c,v)char**v;{und speichern zwei Bytes, sowie zu bewegen , int i=0,p=0,b[9999],*k=b;um außerhalb der Funktion, und legen die int vier Bytes zu speichern. if (c==91)hat auch einen unnötigen Platz.
Es1024
1
Sie können auch die meisten , wenn nicht alle der ersetzen c==[number]?[action]:0;mit c-[number]||[action]. ( c-[number]entspricht c != [number]und if(p)p--;mitp&&p--;
es1024
6

AppleScript 972 670

Meistens Golf gespielt, obwohl es auf keinen Fall jemals gewinnen wird. Ich weiß nicht, warum ich nicht daran gedacht habe, nur ein Skript wie das Perl zu erstellen (obwohl es immer noch nicht gewinnt, haha). Dies könnte wahrscheinlich mehr Golf gespielt werden, indem neu angepasst wird, wie die Indexwerte etwas besser sind. AppleScript ist frustrierend (für diese Art von Sachen) eine 1-Indexsprache.

Übergeben Sie einfach den BrainFlow-Code an e (). Beachten Sie, dass die ASCII-Befehle von AppleScript die MacOSRoman-Codierung verwenden. Die Ausgabe sieht zwar anders aus, ist jedoch in Bezug auf die Binärdarstellung korrekt. Sie müssen dies berücksichtigen, wenn Sie obere ASCII-Zeichen über "," -Befehle übergeben.

on e(x)
set d to {"", "set b'sitem(i+1)to(b'sitem(i+1)+1)mod 256", "set b'sitem(i+1)to(b'sitem(i+1)+255)mod 256", "set i to(i+1)mod 256", "set i to(i+255)mod 256", "repeat while b'sitem(i+1)≠0", "end", "set o to o&(ASCII character b'sitem(i+1))", "display dialog \"\"default answer\"\"
set b'sitem(i+1)to ASCII number result'stext returned'stext1", "set i to b'sitem(i+1)", "set b'sitem(i+1)to i", "set b'sitem(i+1)to b'sitem(b'sitem(i+1)+1)"}
set s to "set i to 0
set b to{}
repeat 256
set b'send to 0
end
set o to  \"\"
"  
repeat with c in x'stext
set s to s&d'sitem((offset of c in "+-><[].,^=&")+1)&"
"
end
set s to s&"return o"
return run script s
end

(denn was ist mehr mit deinem Gehirn zu tun, als einen Brainfuck / Flow-Interpreter in einer anderen Sprache zu schreiben, die viel zu viel mit deinem Kopf zu tun hat?

user0721090601
quelle