Intérprete BrainFlow!

11

BrainFlow

O que é o BrainFlow?

BrainFlow é uma extensão do BrainF ** k (BFk) com 3 comandos adicionais para maior funcionalidade e confusão.

Quais comandos?

Além dos comandos normais do BFk , também temos:

^ Salta para a célula #, dependendo do valor na célula. Ex: se estivermos na célula # 0 com um valor de 4, ^ nos levará para a célula # 4.

= Define o valor na célula para o índice da célula. Ex: se estivermos na célula # 4 com o valor 0, = definirá nosso valor para 4.

& Definirá o valor na célula atual igual ao valor na célula com base no valor em nossa célula atual. (Isso é difícil de dizer, então aqui está um exemplo!) Ex: Estamos na célula # 33 e nosso valor atual nessa célula é 7, e definiremos nosso valor atual na célula # 33 para qualquer valor que esteja na célula # 7.

Desafios opcionais

A realização de uma das seguintes ações aplicará o bônus especificado à sua contagem de bytes.

Interpreter written in BrainFlow (Pode ser interpretado pela amostra e contém pelo menos um ^ = ou & significativo): Pontuação / 3

Interpreter written in BrainF**k: Pontuação / 2

Doesn't contain any English letters (in either upper or lower case): Pontuação - 20

Doesn't contain any of the BrainFlow / BFk commands in the interpreter itself: Pontuação - 50

Exemplo

Um exemplo de interpretador 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;
    }
}

Nem mesmo perto do golfe, mas deve fornecer um bom ponto de partida.

A pontuação final mais baixa vence, em que pontuação é o número de bytes no seu programa após as reduções do Desafio aplicáveis ​​terem sido levadas em consideração.

Teste

O seguinte programa BrainFlow deve imprimir a saída especificada depois de ler um caracter '+' de 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

Resultado:

ðñðòñðòðôóòñóñôóðòõóñõðôôóòñööõôöðóöðõðùõñô÷ùõóñöóùñô÷øôøõôòöõóðòöóñ÷ðõôûôòú÷úø÷öùøöùñøðùúðûðþöûñùýøðòñ
spocot
fonte
Observe que o & permite criar essencialmente variáveis ​​nas células inferiores e referenciá-las mais tarde. Por exemplo, se eu armazenar minha idade na 2ª célula e no mês em que nasci na 3ª célula e atualmente estiver na 64ª célula, posso fazer isso ++&para recuperar minha idade ou +++&recuperar o mês em que nasci. é claro que a célula 64 é o valor padrão 0)
spocot
2
Eu acho que você quer dizer 'superconjunto', não subconjunto.
ɐɔıʇǝɥʇuʎs
@ ɐɔıʇǝɥʇuʎs Alterado de subsetpara extension. Obrigado pelo feedback.
Spocot 28/08/14
A pontuação para ser escrito no fluxo cerebral é uma péssima idéia - brainfuck é um subconjunto do fluxo cerebral, portanto, qualquer programa de brainfuck é um programa de fluxo cerebral. é como dizer que um programa em C ++ terá uma pontuação melhor que um programa em C. OK, o meu programa C é um programa C ++, soo ....
pseudonym117
1
Por que escrever uma implementação em Brainfuck tem um benefício menor do que escrever uma no Brainflow? Parece que o primeiro seria mais desafiador, pois é um idioma menor.
Peter Olson

Respostas:

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

Simplesmente peguei um dos meus intérpretes do BrainFuck, joguei golfe e adicionei as funções do BrainFlow.

Atualização: reestruturou completamente o programa para perder 28 bytes.

Malkaroee
fonte
Observe que, se você receber uma sequência de 300 "+" s, terá valores inválidos. Você precisa fazer uma verificação de sanidade% 256 após / enquanto define muitos desses valores.
User0721090601
Eu acho que isso não funciona com loops ( []). Você não pode avaliar caractere por caractere para isso.
nutki
Como as vantagens são traduzidas novamente entre parênteses?
nutki
6

Vamos começar esta festa.

C - 408384393 390 380 357 352 bytes (ainda se desfazendo)

Compile gccem um sistema compatível com POSIX. O primeiro argumento é o nome de um arquivo que contém o código Brainflow a ser interpretado. Novas linhas adicionadas para melhorar a legibilidade.

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 a versão ungolfed se você estiver interessado. Deixe-me saber se você encontrar algum erro.

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

Atualizações:

  • Obrigado pelo feedback inicial que me permitiu extrair 24 bytes extras.

  • Bug de sinal corrigido. Adicionados outros 9 bytes.

  • Salvo outros 3 bytes de acordo com as sugestões de es1024.

  • Salvo outros 10 bytes por mais sugestões de es1024.

  • Recorde-se que as variáveis ​​globais são inicializadas como 0. Alternadas de fread e fopen para leitura e abertura. 23 bytes salvos.

  • Não é necessário definir o terminador nulo no programa porque o buffer já foi inicializado como zero. Salvo 5 bytes.
Ou pela
fonte
2
Eu acho que o if () e o; pode ser substituído por?: e salve alguns caracteres.
Jerry Jeremiah
2
Os literais de caracteres podem ser substituídos por seus equivalentes ASCII para salvar caracteres.
pseudonym117
1
@ Orby Não parece processar os caracteres de entrada corretamente. Ele deve convertê-los para a representação ascii e armazená-los. Fora isso, funciona.
Spocot 29/08/14
1
Você pode substituir main(int c,char**v){com main(c,v)char**v;{e salvar dois bytes, assim como movimento int i=0,p=0,b[9999],*k=b;para fora da função, e soltar a int salvar quatro bytes. if (c==91)também tem um espaço desnecessário.
precisa saber é o seguinte
1
Você também pode substituir a maioria, se não todas, c==[number]?[action]:0;por c-[number]||[action]. ( c-[number]é equivalente a c != [number]e if(p)p--;comp&&p--;
es1024
6

AppleScript 972 670

Principalmente jogado no golfe, embora nunca tenha como vencer. Não sei por que não pensei em construir um script como o perl (embora ainda não ganhe haha). Provavelmente, isso poderia ser melhor, reajustando o valor do índice um pouco melhor, o AppleScript é frustrantemente (para esse tipo de coisa) uma linguagem de índice 1.

Basta passar o código BrainFlow para e (). Observe que os comandos ASCII do AppleScript usam a codificação MacOSRoman; portanto, embora a saída pareça diferente, é correto observar sua representação binária. Você precisará levar isso em consideração ao passar caracteres ASCII superiores nos comandos ",".

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

(porque o que mais fode com seu cérebro do que escrever um interpretador de fluxo cerebral em outro idioma que fode demais com sua cabeça?

user0721090601
fonte