Compilatore randomizzato Brainfuck


10

Joe è il tuo sviluppatore medio di BF. Sta per controllare le modifiche al codice nel loro repository quando riceve una chiamata dal suo capo. "Joe! La macchina del nuovo client è rotta! L'interprete brainfuck imposta tutte le celle su valori casuali prima dell'esecuzione del programma. Non c'è tempo per sistemarlo, il tuo codice dovrà occuparsene." Joe non ci pensa molto e sta per scrivere un programma per azzerare il primo milione di celle, quando il suo capo lo interrompe di nuovo - "... e non pensare di usare la forza bruta, il codice deve essere il più piccolo possibile ". Ora devi aiutare il povero Joe!

specificazioni

  • Riceverai un codice brainfuck valido come input
  • Il programma modificherà quindi il codice in modo che funzioni su un interprete Brainfuck randomizzato
  • Ciò significa che prima dell'esecuzione del programma, le celle possono essere impostate su qualsiasi valore.
  • Il nuovo programma dovrebbe avere lo stesso identico comportamento, indipendentemente dalle condizioni iniziali.
  • L'interprete avrà un valore di cella max di 255 con avvolgimento e un nastro di lunghezza infinita.

punteggio

Il tuo punteggio è 10 volte la dimensione del compilatore in byte più la somma delle dimensioni del caso di test . Ovviamente vince il punteggio più basso. Per mitigare l'ottimizzazione del caso di test, mi riservo il diritto di modificare i casi di test se sospetto qualcosa, e probabilmente lo farò prima di scegliere un vincitore.

Casi test

(Ho preso questi dalla pagina esolangs e questa pagina web: http://www.hevanet.com/cristofd/brainfuck/ ). Grazie anche a @Sparr per l'ultimo caso di test.

  • Ciao mondo: ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
  • Ingresso inverso: >,[>,]<[.<]
  • Poteri di due (flusso infinito): >++++++++++>>+<+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<]>.>[->[ <++>-[<++>-[<++>-[<++>-[<-------->>[-]++<-[<++>-]]]]]]<[>+<-]+>>]<<]
  • Quadrati inferiori a 10000: ++++[>+++++<-]>[<+++++>-]+<+[>[>+>+<<-]++>>[<<+>>-]>>>[-]++>[-]+>>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<]<<[>>>>>[>>>[-]+++++++++<[>-<-]+++++++++>[-[<->-]+[<<<]]<[>+<-]>]<<-]<<-]
  • Flusso di Fibonacci: >++++++++++>+>+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<<]>.>>[[-]<[>+<-]>>[<<+>+>-]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>>]<<<]
  • Sequenza ASCII fino all'ingresso: ,[.[>+<-]>-](Questo richiede numeri di cella variabili in base all'ingresso)

I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Martin Ender,

Risposte:


8

sed, compilatore da 46 byte

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

Non ho notato che l'output doveva essere anche golf fino a dopo aver scritto il programma, quindi andrò per il breve compilatore. Inoltre, è stato troppo difficile testarlo, quindi si prega di avvisare se non funziona correttamente :)


1
Non ho capito bene. La tua terza riga sostituisce la stringa vuota? Cosa corrisponde alla stringa vuota in sed? "sed: il primo RE potrebbe non essere vuoto"
Sparr

@Sparr Va bene, prova invece con il cursore.
feersum

3
ok, vediamo se seguo ... azzera la cella 0, imposta la cella 1 su una. sostituisci tutti <con << e> con> X>. ora ogni volta che il programma originale accedeva alla cella n il nuovo programma accede alla cella 2n, le celle con numeri pari. X azzera la cella dispari che viene passata e, se non è zero, azzera la cella successiva (una cella pari) e imposta la cella dispari successiva su 1. Ho quello giusto?
Sparr,

2
Sai, se stai per un breve compilatore, questo sarebbe solo 35 byte in Retina . ;)
Martin Ender il

1
@ MartinBüttner spina spudorato! : P
Ottimizzatore

2

C ++

Dimensione del compilatore: 630 byte (-10 byte grazie a Zacharý)
Dimensione del risultato della compilazione di Hello World: 139
Square sotto 10000: 319

Compilatore:

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

L'interprete randomizzato di 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;
    }
}

Alcune note:

  • Il compilatore eseguirà il programma per determinare le celle di memoria utilizzate. Se il tuo programma è un ciclo infinito, il compilatore eseguirà un ciclo infinito.

Puoi ridurre il tuo punteggio cambiando il nome di piia P, cambiando la definizione di Ra m[p<0?p%30000+30000:p]e modificando di conseguenza tutte le chiamate / i riferimenti ad essi. Inoltre, ha modificato i casi di test. Non ho controllato questo, ma potrebbe salvare alcuni byte per definire qualcosa che deve essere 30000, dal momento che lo usi così spesso.
Zacharý,

1
Passerebbe Ral m[p<0?p%S+S:p]lavoro?
Zacharý,

La rimozione delle parentesi nella definizione di Rdovrebbe salvare alcuni byte.
Zacharý,

1

rs , 33 byte, Punteggio: 2659

Principalmente solo una semplice porta della sedrisposta.

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

1
Hai pubblicato questa lingua prima di ieri? Le lingue che postdatano la creazione di una domanda non sono valide per l'invio di risposte.
Sparr,

@Sparr Beh, l'ho fatto, ma poi ho distrutto la mia cronologia di commit Git e ho dovuto ricreare il repository ...
kirbyfan64sos
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.