Переводчик BrainFlow!

11

BrainFlow

Что такое BrainFlow?

BrainFlow - это расширение BrainF ** k (BFk) с 3 дополнительными командами для дополнительной функциональности и путаницы.

Какие команды?

В дополнение к обычным командам BFk у нас также есть:

^ Переход к ячейке # в зависимости от значения в ячейке. Пример: Если мы находимся в ячейке № 0 со значением 4, ^ переместит нас в ячейку № 4.

= Устанавливает значение в ячейке в индекс ячейки. Пример: Если мы находимся в ячейке # 4 со значением 0, = установим наше значение в 4.

& Устанавливает значение в текущей ячейке равным значению в ячейке на основе значения в нашей текущей ячейке. (Это сложно сказать, вот пример!) Пример: Мы находимся в ячейке # 33, и наше текущее значение в этой ячейке равно 7, и мы установим наше текущее значение в ячейке # 33 на любое значение в ячейке # 7.

Дополнительные проблемы

Выполнение любого из перечисленных ниже применяет указанный бонус к вашему счету байтов.

Interpreter written in BrainFlow (Может интерпретироваться образцом и содержит хотя бы один значащий ^ = или &): Оценка / 3

Interpreter written in BrainF**k: Оценка / 2

Doesn't contain any English letters (in either upper or lower case): Оценка - 20

Doesn't contain any of the BrainFlow / BFk commands in the interpreter itself: Оценка - 50

пример

Пример интерпретатора 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;
    }
}

Даже не близко к гольфу, но должен обеспечить хорошую отправную точку.

Наименьший итоговый балл выигрывает, где балл - это количество байтов в вашей программе после того, как были приняты во внимание соответствующие сокращения вызовов.

тестирование

Следующая программа BrainFlow должна напечатать указанный вывод после чтения символа '+' из 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

Выход:

ðñðòñðòðôóòñóñôóðòõóñõðôôóòñööõôöðóöðõðùõñô÷ùõóñöóùñô÷øôøõôòöõóðòöóñ÷ðõôûôòú÷úø÷öùøöùñøðùúðûðþöûñùýøðòñ
spocot
источник
Обратите внимание, что & позволяет вам по существу создавать переменные в нижних ячейках, а затем ссылаться на них позже. Например, если я храню свой возраст во 2-й ячейке и месяц, в котором я родился в 3-й ячейке, а в настоящее время я нахожусь в 64-й ячейке, я могу сделать это, ++&чтобы узнать свой возраст или +++&месяц, в котором я родился. конечно, 64-я ячейка имеет значение по умолчанию 0)
spocot
2
Я думаю, что вы имеете в виду «суперсет», а не подмножество.
Augıʇǝɥʇuʎs
@ ɐɔıʇǝɥʇuʎs изменен с subsetна extension. Спасибо за ответ.
spocot
оценка за то, что она написана в мозговом потоке, является плохой идеей - брейнфук - это подмножество мозгового потока, поэтому любая ментальная программа - это программа мозгового потока. Это все равно что сказать, что программа на С ++ будет лучше, чем программа на Си. Хорошо, моя программа на C - это программа на C ++, так что ...
pseudonym117
1
Почему написание реализации в Brainfuck имеет меньшее преимущество, чем написание в Brainflow? Кажется, что первый будет более сложным, так как это меньший язык.
Питер Олсон,

Ответы:

7

Perl - 233 230 210 182 180 176 174 171 байт

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

Просто взял мой существующий интерпретатор BrainFuck, поиграл в гольф и добавил функции BrainFlow.

Обновление: полностью реструктурирована программа, чтобы потерять 28 байт.

malkaroee
источник
Обратите внимание, что если бы вы получили строку 300 +, вы бы получили недопустимые значения. Вам необходимо выполнить проверку работоспособности% 256 после / во время установки многих из этих значений.
user0721090601
Я думаю, что это не работает с циклами ( []). Вы не можете оценить символ за символом для этого.
Nutki
Как плюсы переводятся обратно в круглые скобки?
Nutki
6

Давайте начнем эту вечеринку.

C - 408 384 393 390 380 357 352 байта (все еще отщепляется)

Компилировать с gccсистемой, совместимой с POSIX. Первый аргумент - это имя файла, содержащего код Brainflow для интерпретации. Добавлены новые строки для улучшения читабельности.

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

И версия без присмотра, если вам интересно. Дайте мне знать, если увидите какие-либо ошибки.

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

Обновления:

  • Спасибо за первоначальный отзыв, который позволил мне сбросить лишние 24 байта.

  • Ошибка со знаком исправлена. Добавлены еще 9 байтов.

  • Сохранено еще 3 байта на предложения es1024.

  • Сохранено еще 10 байтов на дополнительные предложения от es1024.

  • Только что вспомнил, что глобальные переменные инициализируются на 0. Переключены с fread и fopen на чтение и открытие. Сохранено 23 байта.

  • Не нужно устанавливать нулевой терминатор в программе, потому что буфер уже инициализирован на ноль. Сохранено 5 байт.
Orby
источник
2
Я думаю, что если () и; можно заменить на?: и сохранить некоторые символы.
Джерри Иеремия
2
Символьные литералы могут быть заменены их эквивалентами ASCII для сохранения символов.
псевдоним117
1
@Orby Кажется, он неправильно обрабатывает входные символы. Он должен преобразовать их в представление ascii и сохранить их. Помимо этого это работает.
Спокот
1
Вы можете заменить main(int c,char**v){с main(c,v)char**v;{и сохранить два байта, а также двигаться int i=0,p=0,b[9999],*k=b;к внешней функции, и опускать , int чтобы сохранить четыре байта. if (c==91)также имеет ненужное место.
es1024
1
Вы также можете заменить большинство , если не все из c==[number]?[action]:0;с c-[number]||[action]. ( c-[number]эквивалентно c != [number]и if(p)p--;сp&&p--;
es1024
6

AppleScript 972 670

В основном в гольфе, хотя он никогда не победит. Я не знаю, почему я не думал просто о создании скрипта, как это делал perl (хотя он все равно не победит, хаха). Вероятно, это можно было бы сделать лучше, перенастроив то, как значения индекса немного лучше, AppleScript разочаровывает (для такого рода вещей) язык с 1 индексом.

Просто передайте код BrainFlow в e (). Обратите внимание, что в ASCII-командах AppleScript используется кодировка MacOSRoman, поэтому, несмотря на то, что вывод будет выглядеть по-разному, он корректен, если смотреть на его двоичное представление. Вы должны будете принять это во внимание при передаче любых верхних символов ASCII, хотя в командах ",".

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

(потому что, что черт побери, с твоим мозгом больше, чем написание интерпретатора мозгового удара / потока на другом языке, который чересчур сильно болит?

user0721090601
источник