Interprete BrainFlow!


11

BrainFlow

Che cos'è BrainFlow?

BrainFlow è un'estensione di BrainF ** k (BFk) con 3 comandi aggiuntivi per maggiore funzionalità e confusione.

Quali comandi?

Oltre ai normali comandi BFk , abbiamo anche:

^ Passa alla cella # in base al valore nella cella. Es .: Se siamo nella cella # 0 con un valore di 4, ^ ci salterà alla cella # 4.

= Imposta il valore nella cella sull'indice della cella. Esempio: se siamo nella cella n. 4 con un valore pari a 0, = imposterà il nostro valore su 4.

& Imposta il valore nella cella corrente uguale al valore nella cella in base al valore nella nostra cella corrente. (Questo è difficile da pronunciare, quindi ecco un esempio!) Es: Siamo nella cella # 33 e il nostro valore corrente in questa cella è 7, e imposteremo il nostro valore corrente nella cella # 33 su qualunque valore sia nella cella # 7.

Sfide opzionali

Compiere uno dei seguenti applica il bonus specificato al conteggio dei byte.

Interpreter written in BrainFlow (Può essere interpretato dal campione e contiene almeno un significativo ^ = o &): Punteggio / 3

Interpreter written in BrainF**k: Punteggio / 2

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

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

Esempio

Un esempio di interprete Java:

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;
    }
}

Nemmeno vicino al golf, ma dovrebbe fornire un buon punto di partenza.

Il punteggio finale più basso vince, dove il punteggio è il numero di byte nel programma dopo che sono state prese in considerazione le riduzioni della Sfida applicabili.

analisi

Il seguente programma BrainFlow dovrebbe stampare l'output specificato dopo aver letto un carattere '+' da stdin:

<<,++++[>++++[>++++<-]<-] 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

Produzione:

ðñðòñðòðôóòñóñôóðòõóñõðôôóòñööõôöðóöðõðùõñô÷ùõóñöóùñô÷øôøõôòöõóðòöóñ÷ðõôûôòú÷úø÷öùøöùñøðùúðûðþöûñùýøðòñ

Si noti che il & consente di creare essenzialmente variabili nelle celle inferiori, quindi fare riferimento in un secondo momento. Ad esempio, se conservo la mia età nella 2a cella e il mese in cui sono nato nella 3a cellula, e attualmente mi trovo nella 64a cellula, posso fare ++&per recuperare la mia età o +++&per recuperare il mese in cui sono nato. (Supponendo ovviamente la 64a cella ha il valore predefinito di 0)
spocot

2
Penso che intendi "superset", non sottoinsieme.
Augıʇǝɥʇuʎs,

@ ɐɔıʇǝɥʇuʎs Modificato da subseta extension. Grazie per il feedback.
spocot

il punteggio per essere scritto in brainflow è una cattiva idea - brainfuck è un sottoinsieme di brainflow, quindi qualsiasi programma brainfuck è un programma brainflow. è come dire che un programma c ++ avrà un punteggio migliore di un programma C. OK, il mio programma C è un programma C ++, quindi ...
pseudonimo117

1
Perché scrivere un'implementazione in Brainfuck ha un vantaggio minore rispetto a scriverne una in Brainflow? Sembra che il primo sarebbe più impegnativo, dal momento che è una lingua più piccola.
Peter Olson,

Risposte:


7

Perl - 233 230 210 182 180 176 174 171 byte

$/=$,;%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

Ho semplicemente preso un mio interprete BrainFuck esistente, l'ho giocato a golf e ho aggiunto le funzioni BrainFlow.

Aggiornamento: Completamente ristrutturato il programma per perdere 28 byte.


Nota che se dovessi ricevere una stringa di 300 "+" s, finiresti con valori non validi. È necessario eseguire un controllo di integrità% 256 dopo / durante l'impostazione di molti di questi valori.
user0721090601

Penso che questo non funzioni con i loop ( []). Non puoi valutare carattere per carattere per quello.
Nutki,

Come i vantaggi vengono tradotti di nuovo in parentesi?
Nutki,

6

Diamo inizio alla festa.

C - 408 384 393 390 380 357 352 byte (ancora scheggiandosi)

Compilare con gccun sistema conforme a POSIX. Il primo argomento è il nome di un file contenente il codice Brainflow da interpretare. Newline aggiunte per migliorare la leggibilità.

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;}}}

E la versione non golfata se sei interessato. Fammi sapere se vedi qualche bug.

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;
            }
    }
}

aggiornamenti:

  • Grazie per il feedback iniziale che mi ha permesso di eliminare altri 24 byte.

  • Bug del bug risolto. Aggiunti altri 9 byte.

  • Salvati altri 3 byte per i suggerimenti di es1024.

  • Salvati altri 10 byte per ulteriori suggerimenti da es1024.

  • Ho appena ricordato che le variabili globali sono inizializzate su 0. Passato da fread e fopen a lettura e apertura. Salvato 23 byte.

  • Non è necessario impostare il terminatore null sul programma perché il buffer è già inizializzato su zero. 5 byte salvati.

2
Penso che if () e; potrebbe essere sostituito con?: e salvare alcuni caratteri.
Jerry Jeremiah,

2
I letterali dei caratteri possono essere sostituiti con i loro equivalenti ASCII per salvare i caratteri.
pseudonimo117,

1
@Orby Non sembra elaborare correttamente i caratteri di input. Dovrebbe convertirli nella rappresentazione ASCII e archiviarli. Diverso da quello che funziona.
spocot

1
È possibile sostituire main(int c,char**v){con main(c,v)char**v;{e salvare due byte, nonché spostarsi int i=0,p=0,b[9999],*k=b;all'esterno della funzione e rilasciarlo int per salvare quattro byte. if (c==91)ha anche uno spazio non necessario.
es1024,

1
Puoi anche sostituire la maggior parte, se non tutte, c==[number]?[action]:0;con c-[number]||[action]. ( c-[number]È equivalente a c != [number]e if(p)p--;conp&&p--;
es1024

6

AppleScript 972 670

Principalmente giocato a golf, anche se non potrà mai vincere. Non so perché non abbia pensato di costruire solo una sceneggiatura come quella perl (anche se non vincerà ancora ahah). Questo potrebbe probabilmente essere risolto maggiormente aggiustando come l'indice valorizza un po 'meglio, AppleScript è frustrante (per questo tipo di cose) un linguaggio di 1 indice.

Basta passare il codice BrainFlow a e (). Nota che i comandi ASCII di AppleScript usano la codifica MacOSRoman, quindi mentre l'output apparirà diverso, è corretto osservarne la rappresentazione binaria. Dovrai tenerne conto quando passi i caratteri ASCII superiori tramite i comandi ",".

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

(perché che fottuto di più del tuo cervello se non quello di scrivere un interprete brainfuck / flow in un'altra lingua che fottiti troppo con la testa?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.