Перекладач 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 повинна надрукувати вказаний вихід після зчитування знака "+" зі стину:

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

Вихід:

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

Зауважте, що & дозволяє по суті створювати змінні в нижчих осередках, а потім посилатися на них пізніше. Наприклад, якщо я зберігаю свій вік у 2-й камері та місяць, коли я народився в 3-й клітині, і зараз я перебуваю у 64-й клітині, я можу зробити, ++&щоб отримати свій вік або +++&отримати місяць, у якому я народився. звичайно 64-й осередок знаходиться за замовчуванням 0)
спокот

2
Я думаю, ви маєте на увазі «суперсеть», а не підмножина.
ɐɔıʇǝɥʇuʎs

@ ɐɔıʇǝɥʇuʎs Змінено з subsetна extension. Дякуємо за відгук.
spocot

оцінка за те, що записана в мозковий потік - це погана ідея - brainfuck - це підмножина мозкового потоку, тому будь-яка програма для епізодів є програмою мозкового потоку. як би сказати, що програма c ++ отримає кращий результат, ніж програма C. Гаразд, моя програма C - це програма C ++, су ....
псевдонім117,

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 байт.


Зауважте, що якби вам подавали рядок 300 "+" s, ви отримаєте недійсні значення. Вам потрібно зробити перевірку рівня безпеки на 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 байт.

2
Я думаю, що if () і the; може бути замінено?: і зберегти деякі символи.
Джеррі Єремія

2
Літеральні символи можуть бути замінені на їх еквіваленти ASCII, щоб зберегти символи.
псевдонім117

1
@Orby Схоже, неправильно обробляти символи введення. Він повинен перетворити їх у представлення ascii та зберігати їх. Крім того, що це працює.
spocot

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

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

Просто передайте код BrainFlow в e (). Зауважте, що в командах AppleScript ASCII використовується кодування 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

(тому що, що f *** s вашому мозку більше, ніж писати перекладача мозкових перекладів / потоку на іншій мові, що f *** s з головою занадто багато?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.