Рандомизированный компилятор Brainfuck

10

Джо - ваш средний разработчик BF. Он собирается проверить изменения своего кода в их хранилище, когда ему позвонит его начальник. «Джо! Машина нового клиента сломана! Интерпретатор brainfuck устанавливает все ячейки в случайные значения перед выполнением программы. Нет времени, чтобы исправить это, ваш код должен будет с этим справиться». Джо не задумывается об этом и собирается написать программу, которая обнулит первый миллион ячеек, когда его начальник снова его прерывает - «... и не думайте об использовании грубой силы, код должен будь как можно меньше. " Теперь ты должен помочь бедному Джо!

Характеристики

  • Вы получите действительный код Brainfuck в качестве ввода
  • Ваша программа затем модифицирует код так, чтобы он работал на рандомизированном интерпретаторе бредов
  • Это означает, что перед выполнением программы ячейки могут быть установлены на любое значение.
  • Новая программа должна иметь одинаковое поведение независимо от начальных условий.
  • Интерпретатор будет иметь значение максимальной ячейки 255 с переносом и ленту бесконечной длины.

счет

Ваша оценка в 10 раз больше размера компилятора в байтах плюс сумма размеров тестового набора . Очевидно, что выигрывает самый низкий балл. Чтобы смягчить последствия оптимизации тестовых примеров, я оставляю за собой право изменить тестовые примеры, если я что-то подозреваю, и, вероятно, сделаю это до выбора победителя.

Тестовые случаи

(Я получил их со страницы esolangs и этой веб-страницы: http://www.hevanet.com/cristofd/brainfuck/ ). Также спасибо @Sparr за последний контрольный пример.

  • Привет мир: ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
  • Обратный вход: >,[>,]<[.<]
  • Полномочия Двух (Бесконечный Поток): >++++++++++>>+<+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<]>.>[->[ <++>-[<++>-[<++>-[<++>-[<-------->>[-]++<-[<++>-]]]]]]<[>+<-]+>>]<<]
  • Квадраты до 10000: ++++[>+++++<-]>[<+++++>-]+<+[>[>+>+<<-]++>>[<<+>>-]>>>[-]++>[-]+>>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<]<<[>>>>>[>>>[-]+++++++++<[>-<-]+++++++++>[-[<->-]+[<<<]]<[>+<-]>]<<-]<<-]
  • Поток Фибоначчи: >++++++++++>+>+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<<]>.>>[[-]<[>+<-]>>[<<+>+>-]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>>]<<<]
  • Последовательность ASCII до ввода: ,[.[>+<-]>-](для этого требуется изменение количества ячеек в зависимости от ввода)
Maltysen
источник
Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
Мартин Эндер

Ответы:

8

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

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

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

feersum
источник
1
Я смущен. Ваша третья строка заменяет пустую строку? Что соответствует пустой строке в sed? "sed: first RE не может быть пустым"
Спарр
@Sparr Ладно, попробуй вместо карета.
feersum
3
Хорошо, давайте посмотрим, если я следую ... обнулить ячейку 0, установить ячейку 1 в единицу. заменить все <на << и> на> X>. теперь каждый раз, когда исходная программа обращается к ячейке n, новая программа обращается к ячейке 2n, четным ячейкам. X обнуляет пропускаемую нечетную ячейку, и если она не равна нулю, она обнуляет следующую ячейку (четную) и устанавливает следующую нечетную ячейку равной 1. Имею ли я это право?
Спарр
2
Знаете, если вы собираетесь использовать короткий компилятор, в Retina это будет всего 35 байт . ;)
Мартин Эндер
1
@ MartinBüttner бесстыдная вилка! : P
Оптимизатор
2

C ++

Размер компилятора: 630 байт (благодаря Zacharý -10 байт)
Размер результата компиляции 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;}

Рандомизированный интерпретатор Brainfuck:

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

Некоторые заметки:

  • Компилятор выполнит программу, чтобы определить используемые ячейки памяти. Если ваша программа представляет собой бесконечный цикл, компилятор будет выполнять бесконечный цикл.
HatsuPointerKun
источник
Вы можете уменьшить свой счет, изменив имя piiна Pи изменив определение Rна m[p<0?p%30000+30000:p]и изменив все вызовы / ссылки на них соответственно. Также он модифицировал тестовые случаи. Я не проверял это, но он может сохранить несколько байтов, чтобы определить, что нужно 30000, так как вы используете это так часто.
Захари
1
Будет ли меняться Rна m[p<0?p%S+S:p]работу?
Захари
Удаление скобок в определении Rдолжно сэкономить несколько байтов.
Захари
1

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

В основном просто порт sedответа.

</<<
>/>[->[-]>[-]+<<]>
[-]>[-]+<
kirbyfan64sos
источник
1
Вы опубликовали этот язык до вчерашнего дня? Языки, которые датируют создание вопроса, недопустимы для отправки ответов.
Спарр
@Sparr Ну, у меня было, но потом я разрушил историю коммитов в Git и мне пришлось заново создать репо ...
kirbyfan64sos