Tłumacz BrainFlow!

11

BrainFlow

Co to jest BrainFlow?

BrainFlow to rozszerzenie BrainF ** k (BFk) z 3 dodatkowymi poleceniami dla dodatkowej funkcjonalności i zamieszania.

Jakie polecenia?

Oprócz zwykłych poleceń BFk , mamy również:

^ Przeskakuje do komórki # w zależności od wartości w komórce. Np .: Jeśli jesteśmy w komórce nr 0 o wartości 4, ^ przeskoczy nas do komórki nr 4.

= Ustawia wartość w komórce na indeks komórki. Np .: jeśli znajdujemy się w komórce 4 o wartości 0, = ustawi naszą wartość na 4.

& Ustawi wartość w bieżącej komórce równą wartości w komórce na podstawie wartości w naszej bieżącej komórce. (Ten jest trudny do sformułowania, więc oto przykład!) Np .: Jesteśmy w komórce nr 33, a nasza obecna wartość w tej komórce wynosi 7 i ustawimy naszą bieżącą wartość w komórce nr 33 na dowolną wartość w komórce nr 7.

Opcjonalne wyzwania

Wykonanie dowolnego z poniższych działań spowoduje zastosowanie określonej premii do liczby bajtów.

Interpreter written in BrainFlow (Może być zinterpretowany przez próbkę i zawiera co najmniej jeden znaczący ^ = lub &): Wynik / 3

Interpreter written in BrainF**k: Wynik / 2

Doesn't contain any English letters (in either upper or lower case): Wynik - 20

Doesn't contain any of the BrainFlow / BFk commands in the interpreter itself: Wynik - 50

Przykład

Przykładowy interpreter 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;
    }
}

Nawet nie blisko golfa, ale powinien być dobrym punktem wyjścia.

Najniższy wynik końcowy wygrywa, gdzie wynikiem jest liczba bajtów w twoim programie po uwzględnieniu odpowiednich redukcji Wyzwania.

Testowanie

Poniższy program BrainFlow powinien wydrukować określone dane wyjściowe po odczytaniu znaku „+” ze standardowego wejścia:

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

Wynik:

ðñðòñðòðôóòñóñôóðòõóñõðôôóòñööõôöðóöðõðùõñô÷ùõóñöóùñô÷øôøõôòöõóðòöóñ÷ðõôûôòú÷úø÷öùøöùñøðùúðûðþöûñùýøðòñ
spocot
źródło
Zauważ, że & pozwala zasadniczo tworzyć zmienne w dolnych komórkach, a następnie odwoływać się do nich później. Na przykład, jeśli przechowuję swój wiek w 2. komórce, a miesiąc, w którym się urodziłem, w 3. komórce, a obecnie jestem w 64. komórce, mogę zrobić, ++&aby odzyskać swój wiek lub +++&miesiąc, w którym się urodziłem. (Zakładając oczywiście 64. komórka ma domyślną wartość 0)
spocot
2
Myślę, że masz na myśli „superset”, a nie podzbiór.
Augıʇǝɥʇuʎs
@ ɐɔıʇǝɥʇuʎs Zmieniono z subsetna extension. Dziękuję za opinię.
spocot
wynik za napisanie w przepływie mózgu jest złym pomysłem - pieprzenie mózgu jest podzbiorem przepływu mózgów, dlatego każdy program pieprzenia mózgu jest programem przepływu mózgów. to tak, jakby powiedzieć, że program c ++ uzyska lepszy wynik niż program C. OK, mój program C to program w C ++, soo ....
pseudonim117,
1
Dlaczego pisanie implementacji w Brainfuck ma mniejszą zaletę niż pisanie w Brainflow? Wydaje się, że ten pierwszy byłby trudniejszy, ponieważ jest to mniejszy język.
Peter Olson,

Odpowiedzi:

7

Perl - 233 230 210 182 180 176 176 177 bajtów

$/=$,;%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

Po prostu wziąłem mojego istniejącego interpretera BrainFuck, grałem w golfa i dodałem funkcje BrainFlow.

Aktualizacja: Całkowicie zrestrukturyzowano program, aby stracił 28 bajtów.

Malkaroee
źródło
Zwróć uwagę, że jeśli miałbyś otrzymać ciąg 300 „+”, otrzymałeś niepoprawne wartości. Musisz wykonać sprawdzenie poprawności% 256 po / podczas ustawiania wielu z tych wartości.
user0721090601
Myślę, że to nie działa z pętlami ( []). Nie można w tym celu ewaluować postaci po postaci.
nutki
Jak plusy zamieniają się z powrotem w nawiasy?
nutki
6

Zacznijmy tą imprezę.

C - 408 384 393 390 380 357 352 bajtów (wciąż odpryskuje)

Kompiluj z gccsystemem zgodnym z POSIX. Pierwszy argument to nazwa pliku zawierającego kod Brainflow do interpretacji. Dodano nowe linie, aby poprawić czytelność.

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

I wersja bez golfa, jeśli jesteś zainteresowany. Daj mi znać, jeśli zobaczysz jakieś błędy.

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

Aktualizacje:

  • Dzięki za wstępną informację zwrotną, która pozwoliła mi zrzucić dodatkowe 24 bajty.

  • Naprawiono błąd znaku. Dodano kolejne 9 bajtów.

  • Zapisano kolejne 3 bajty na sugestie es1024.

  • Zapisano kolejne 10 bajtów na więcej sugestii z es1024.

  • Właśnie pamiętam, że zmienne globalne są inicjowane na 0. Przełączono z fread i fopen na czytanie i otwieranie. Zapisano 23 bajty.

  • Nie trzeba ustawiać terminatora zerowego w programie, ponieważ bufor jest już zainicjowany na zero. Zapisano 5 bajtów.
Lub przez
źródło
2
Myślę, że if () i; można zastąpić?: i zapisać niektóre znaki.
Jerry Jeremiah
2
Literały znaków można zastąpić ich odpowiednikami ASCII, aby zapisać znaki.
pseudonim
1
@Orby Nie wydaje się poprawnie przetwarzać znaków wejściowych. Powinien przekonwertować je na reprezentację ascii i przechowywać. Poza tym to działa.
spocot
1
Można wymienić main(int c,char**v){z main(c,v)char**v;{zaoszczędzisz dwa bajty, a także przenieść int i=0,p=0,b[9999],*k=b;na zewnątrz funkcji i upuść int , aby zapisać cztery bajty. if (c==91)ma również niepotrzebne miejsce.
es1024,
1
Można również zastąpić większość, jeśli nie wszystkie c==[number]?[action]:0;z c-[number]||[action]. ( c-[number]Odpowiada c != [number]i if(p)p--;zep&&p--;
es1024
6

AppleScript 972 670

Głównie grał w golfa, choć nie ma szans, aby wygrał. Nie wiem, dlaczego nie pomyślałem o stworzeniu skryptu takiego jak Perl (choć nadal nie wygra haha). Prawdopodobnie można by to pograć w golfa, zmieniając nieco wartość indeksu. AppleScript jest frustrująco (jak na tego typu rzeczy) 1 językiem indeksu.

Wystarczy przekazać kod BrainFlow do e (). Zauważ, że polecenia ASCII AppleScript używają kodowania MacOSRoman, więc chociaż dane wyjściowe będą wyglądać inaczej, poprawne jest spojrzenie na ich reprezentację binarną. Trzeba to wziąć pod uwagę, przekazując dowolne górne znaki ASCII za pomocą poleceń „,”.

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

(bo co kurwa jest z twoim mózgiem bardziej niż pisanie bzdury / tłumacza w innym języku, który cholernie za bardzo boli ci głowę?

użytkownik 0721090601
źródło