Randomized Brainfuck Compiler

10

Joe jest twoim przeciętnym programistą BF. Ma zamiar sprawdzić zmiany swojego kodu w repozytorium, gdy otrzyma telefon od swojego szefa. „Joe! Maszyna nowego klienta jest zepsuta! Interpretator ustawia wszystkie komórki na losowe wartości przed wykonaniem programu. Nie ma czasu na naprawę, twój kod będzie musiał sobie z tym poradzić.” Joe nie myśli o tym zbyt wiele i ma zamiar napisać program, który wyzeruje pierwszy milion komórek, gdy jego szef ponownie mu przerywa - „... i nie myśl o użyciu brutalnej siły, kod musi być tak mały, jak to możliwe. ” Teraz musisz pomóc biednemu Joe!

Dane techniczne

  • Otrzymasz jakiś poprawny kod pieprzenia mózgu jako dane wejściowe
  • Twój program następnie zmodyfikuje kod, aby działał na losowym interpretatorze pieprzenia mózgu
  • Oznacza to, że przed wykonaniem programu komórki można ustawić na dowolną wartość.
  • Nowy program powinien mieć dokładnie takie samo zachowanie bez względu na warunki początkowe.
  • Interpretator będzie miał maksymalną wartość 255 z owinięciem i taśmę o nieskończonej długości.

Punktacja

Twój wynik to 10-krotność wielkości kompilatora w bajtach plus suma rozmiarów przypadków testowych . Najniższy wynik oczywiście wygrywa. Aby złagodzić optymalizację przypadków testowych, zastrzegam sobie prawo do zmiany przypadków testowych, jeśli coś podejrzewam, i prawdopodobnie zrobi to przed wyborem zwycięzcy.

Przypadki testowe

(Mam je ze strony esolangs i tej strony: http://www.hevanet.com/cristofd/brainfuck/ ). Również dzięki @Sparr za ostatni przypadek testowy.

  • Witaj świecie: ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
  • Odwrotne wejście: >,[>,]<[.<]
  • Powers of Two (Infinite Stream): >++++++++++>>+<+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<]>.>[->[ <++>-[<++>-[<++>-[<++>-[<-------->>[-]++<-[<++>-]]]]]]<[>+<-]+>>]<<]
  • Kwadraty poniżej 10000: ++++[>+++++<-]>[<+++++>-]+<+[>[>+>+<<-]++>>[<<+>>-]>>>[-]++>[-]+>>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<]<<[>>>>>[>>>[-]+++++++++<[>-<-]+++++++++>[-[<->-]+[<<<]]<[>+<-]>]<<-]<<-]
  • Strumień Fibonacciego: >++++++++++>+>+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<<]>.>>[[-]<[>+<-]>>[<<+>+>-]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>>]<<<]
  • Sekwencja ASCII do danych wejściowych: ,[.[>+<-]>-](Ta wymaga różnych liczb komórek w zależności od danych wejściowych)
Maltysen
źródło
Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
Martin Ender

Odpowiedzi:

8

sed, 46-bajtowy kompilator

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

Dopiero po napisaniu programu nie zauważyłem, że wyjście miało być golfem, więc wybiorę krótki kompilator. Również testowanie było zbyt pracochłonne, więc proszę powiadomić, jeśli nie działa poprawnie :)

feersum
źródło
1
Jestem zmieszany. Twój trzeci wiersz zastępuje pusty ciąg? Co pasuje pusty ciąg w sed? „sed: first RE może nie być pusty”
Sparr
@Sparr W porządku, spróbuj zamiast tego z karetką.
feersum
3
ok, zobaczmy, czy podążę ... wyzeruj komórkę 0, ustaw komórkę 1 na jedną. zamień wszystkie <na << i> na> X>. teraz za każdym razem, gdy oryginalny program uzyskuje dostęp do komórki n, nowy program uzyskuje dostęp do komórki 2n, komórek parzystych. X zeruje nieparzystą komórkę, która jest przekazywana, a jeśli nie jest zerowa, zeruje następną komórkę (komórkę parzystą) i ustawia następną nieparzystą komórkę na 1. czy mam to prawo?
Sparr
2
Wiesz, jeśli wybierasz krótki kompilator, w Retinie byłoby to tylko 35 bajtów . ;)
Martin Ender
1
@ MartinBüttner bezwstydna wtyczka! : P
Optymalizator
2

C ++

Rozmiar kompilatora: 630 bajtów (-10 bajtów dzięki Zacharýowi)
Rozmiar wyniku kompilacji Hello World: 139
Kwadrat poniżej 10000: 319

Kompilator:

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

Randomizowany tłumacz pieprzony mózg:

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

Niektóre uwagi:

  • Kompilator uruchomi program w celu ustalenia używanych komórek pamięci. Jeśli twój program jest nieskończoną pętlą, kompilator zapętla się w nieskończoność.
HatsuPointerKun
źródło
Możesz zmniejszyć swój wynik, zmieniając nazwę piina Pi zmieniając definicję Rna m[p<0?p%30000+30000:p]oraz odpowiednio modyfikując wszystkie połączenia / odniesienia do nich. Zmodyfikował także przypadki testowe. Nie sprawdziłem tego, ale może zaoszczędzić trochę bajtów, aby zdefiniować coś 30000, ponieważ tak często go używasz.
Zacharý
1
Czy przejście Rdo m[p<0?p%S+S:p]pracy?
Zacharý
Usunięcie nawiasów w definicji Rpowinno zaoszczędzić kilka bajtów.
Zacharý
1

rs , 33 bajty, wynik: 2659

Przeważnie tylko prosty port sedodpowiedzi.

</<<
>/>[->[-]>[-]+<<]>
[-]>[-]+<
kirbyfan64sos
źródło
1
Czy opublikowałeś ten język przed wczoraj? Języki, które powstały po utworzeniu pytania, nie nadają się do przesyłania odpowiedzi.
Sparr
@Sparr Cóż, miałem, ale potem zniszczyłem historię zatwierdzeń Git i musiałem odtworzyć repo ...
kirbyfan64sos