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:

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

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.


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.

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?

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.