Довільний компілятор Brainfuck


10

Джо - ваш середній розробник BF. Він збирається перевірити в своєму коді зміни в їх сховищі, коли він отримає дзвінок від свого шефа. "Джо! Машина нового клієнта зламана! Інтерпретатор brainfuck встановлює всі комірки на випадкові значення перед виконанням програми. Немає часу, щоб виправити це, ваш код повинен буде з цим боротися." Джо не дуже думає про це, і збирається написати програму для встановлення першого мільйона комірок на нуль, коли його начальник перерве його знову - "... і не думайте про використання грубої сили, код повинен бути якомога меншим ". Тепер ви повинні допомогти бідному Джо!

Технічні умови

  • Ви отримаєте якийсь дійсний код, який є мозком
  • Потім ваша програма змінить код так, щоб він працював на рандомізованому перекладачеві епізодів
  • Це означає, що перед виконанням програми клітинкам можна встановити будь-яке значення.
  • Нова програма повинна мати таку саму поведінку, незалежно від початкових умов.
  • Інтерпретатор матиме значення максимальної комірки 255 із загортанням та стрічкою нескінченної довжини.

Оцінка балів

Ваш бал у 10 разів перевищує розмір компілятора в байтах плюс сума розмірів тестових випадків . Очевидно, що найнижчий бал виграє. Щоб пом'якшити процес оптимізації тестових випадків, я залишаю за собою право змінювати тестові справи, якщо я щось підозрюю, і, мабуть, зроблю це перед тим, як вибрати переможця.

Випробування

(Я отримав їх зі сторінки esolangs та цієї веб-сторінки: http://www.hevanet.com/cristofd/brainfuck/ ). Також дякую @Sparr за останній тестовий випадок.

  • Привіт Світ: ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
  • Зворотний вхід: >,[>,]<[.<]
  • Сили двох (нескінченний потік): >++++++++++>>+<+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<]>.>[->[ <++>-[<++>-[<++>-[<++>-[<-------->>[-]++<-[<++>-]]]]]]<[>+<-]+>>]<<]
  • Квадрати до 10000: ++++[>+++++<-]>[<+++++>-]+<+[>[>+>+<<-]++>>[<<+>>-]>>>[-]++>[-]+>>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<]<<[>>>>>[>>>[-]+++++++++<[>-<-]+++++++++>[-[<->-]+[<<<]]<[>+<-]>]<<-]<<-]
  • Потік Фібоначчі: >++++++++++>+>+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<<]>.>>[[-]<[>+<-]>>[<<+>+>-]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>>]<<<]
  • Послідовність ASCII до введення: ,[.[>+<-]>-](Для цього потрібні різні числа комірок залежно від введення)

Коментарі не для розширеного обговорення; ця розмова була переміщена до чату .
Мартін Ендер

Відповіді:


8

sed, 46-байтний компілятор

s/</<</g
s/>/>[->[-]>[-]+<<]>/g
s/^/[-]>[-]+</

Я не помітив, що вихід також повинен був бути гольфом до написання програми, тому я піду на короткий компілятор. Також для тестування було занадто багато роботи, тому повідомте, якщо вона не працює належним чином :)


1
Я збентежений. Ваш третій рядок замінює порожній рядок? Що відповідає порожній рядок у sed? "sed: перший RE може бути порожнім"
Sparr

@Sparr Добре, спробуйте замість цього з каретою.
feersum

3
ОК, давайте подивимось, чи я дотримуюся ... нуль комірки 0, встановіть комірку 1 на одиницю. замініть всі <на << і> з> X>. тепер будь-який час, коли оригінальна програма отримувала доступ до клітинки n, нова програма отримує доступ до комірки 2n, парних комірок. X нулі непарної комірки передається, і якщо вона не дорівнює нулю, то вона нульовує наступну клітинку (парну комірку) і встановлює наступну непарну комірку на 1. Чи я маю це правильно?
Спарр

2
Ви знаєте, якщо ви збираєтесь короткий компілятор, це було б лише 35 байт у Retina . ;)
Мартін Ендер

1
@ MartinBüttner безсоромний штекер! : P
Оптимізатор

2

C ++

Розмір компілятора: 630 байт (-10 байт завдяки Zacharý)
Розмір результату компіляції Hello World: 139
Квадрат під 10000: 319

Компілятор:

#include<string>
#include<map>
#include<stack>
#define B break
#define C case
#define S 30000
#define R m[(p<0)?(p%S)+S:p]
using s=std::string;using P=std::pair<int,int>;s a(s c){char m[S];memset(m,0,S);int p=0,i=0;P r{0,0};std::map<int,int>j;std::stack<int>t;for(int d=0;d<c.size();++d){if(c[d]==91)t.push(d);if(c[d]==93){j[d]=t.top();j[t.top()]=d;t.pop();}}while(i<c.size()){switch(c[i]){C'>':++p;B;C'<':--p;B;C'+':++R;B;C'-':--R;B;C'[':if(!R)i=j[i];B;C']':i=j[i]-1;B;default:B;}++i;r.first=p<r.first?p:r.first;r.second=p>r.second?p:r.second;}s n;for(int i=r.first;i<r.second;++i){n+="[-]>";}n+="[-]"+s(r.second,60)+c;return n;}

Рандомізований перекладач мозкових ебать:

void interpret(const std::string& code) {
    char memory[30000];
    for (int i = 0; i < 30000; ++i)
        memory[i] = std::rand()%256;
    int memPtr = 0, insPtr = 0;
    std::map<int, int> jump_map;

    {
        std::stack<int> jstack;
        for (int i = 0; i < code.size(); ++i) {
            if (code[i] == '[')
                jstack.push(i);
            if (code[i] == ']') {
                jump_map[i] = jstack.top();
                jump_map[jstack.top()] = i;
                jstack.pop();
            }
        }
    }
    while (insPtr < code.size()) {
        switch (code[insPtr]) {
        case '>': ++memPtr; break;
        case '<': --memPtr; break;
        case '+': ++memory[memPtr]; break;
        case '-': --memory[memPtr]; break;
        case '.': std::cout << memory[memPtr]; break;
        case ',': std::cin >> memory[memPtr]; break;
        case ']': if (memory[memPtr] != 0) insPtr = jump_map[insPtr]; break;
        case '[': if (memory[memPtr] == 0) insPtr = jump_map[insPtr]; break;
        default:break;
        }
        ++insPtr;
    }
}

Деякі примітки:

  • Компілятор виконає програму для визначення комірок пам'яті, які використовуються. Якщо ваша програма є нескінченним циклом, компілятор буде циклічно нескінченним.

Ви можете зменшити свій рахунок, змінивши назву piiна P, і змінити визначення Rдо m[p<0?p%30000+30000:p], і зміни всіх викликів / посилання на них відповідним чином . Також він модифікував тестові приклади. Я цього не перевіряв, але це може зберегти кілька байтів, щоб визначити щось таке 30000, оскільки ви використовуєте його так часто.
Zacharý

1
Чи змінилася Rб m[p<0?p%S+S:p]робота?
Zacharý

Видалення дужок у визначенні Rмає зберегти кілька байтів.
Zacharý

1

rs , 33 байти, оцінка: 2659

Здебільшого просто простий порт sedвідповіді.

</<<
>/>[->[-]>[-]+<<]>
[-]>[-]+<

1
Ви публікували цю мову до вчорашнього дня? Мови, які відкладають створення запитання, не дійсні для надсилання відповідей.
Спарр

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