Penerjemah BrainFlow!

11

BrainFlow

Apa itu BrainFlow?

BrainFlow adalah perpanjangan dari BrainF ** k (BFk) dengan 3 perintah tambahan untuk menambah fungsionalitas dan kebingungan.

Perintah apa?

Selain perintah BFk normal , kami juga memiliki:

^ Melompat ke sel # tergantung pada nilai dalam sel. Mis: Jika kita berada di sel # 0 dengan nilai 4, ^ akan melompat kita ke sel # 4.

= Menetapkan nilai pada sel ke indeks sel. Mis: Jika kita berada di sel # 4 dengan nilai 0, = akan menetapkan nilai kita menjadi 4.

& Akan menetapkan nilai pada sel saat ini sama dengan nilai pada sel berdasarkan pada nilai di sel kami saat ini. (Yang ini sulit untuk dikatakan, jadi inilah contohnya!) Mis: Kami berada di sel # 33 dan nilai kami saat ini di sel ini adalah 7, & akan menetapkan nilai kami saat ini di sel # 33 untuk nilai apa pun yang ada di sel # 7.

Tantangan Opsional

Menyelesaikan salah satu dari yang berikut ini akan menerapkan bonus yang ditentukan untuk jumlah byte Anda.

Interpreter written in BrainFlow (Dapat ditafsirkan oleh sampel dan mengandung setidaknya satu bermakna ^ = atau &): Skor / 3

Interpreter written in BrainF**k: Skor / 2

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

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

Contoh

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

Bahkan tidak dekat dengan golf tetapi harus memberikan titik awal yang baik.

Skor final terendah menang, di mana skor adalah jumlah byte dalam program Anda setelah pengurangan Tantangan yang berlaku telah diperhitungkan.

Pengujian

Program BrainFlow berikut harus mencetak output yang ditentukan setelah membaca karakter '+' dari stdin:

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

Keluaran:

ðñðòñðòðôóòñóñôóðòõóñõðôôóòñööõôöðóöðõðùõñô÷ùõóñöóùñô÷øôøõôòöõóðòöóñ÷ðõôûôòú÷úø÷öùøöùñøðùúðûðþöûñùýøðòñ
spocot
sumber
Perhatikan bahwa & memungkinkan Anda untuk secara esensial membuat variabel di sel yang lebih rendah kemudian referensi mereka nanti. Misalnya jika saya menyimpan usia saya di sel ke-2 dan bulan saya dilahirkan di sel ke-3, dan saya saat ini di sel ke-64, saya bisa lakukan ++&untuk mengambil umur saya atau +++&untuk mengambil bulan di mana saya dilahirkan. (Asumsikan tentu saja sel ke-64 berada pada nilai default 0)
spocot
2
Saya pikir maksud Anda 'superset', bukan subset.
ɐɔıʇǝɥʇu
@ ɐɔıʇǝɥʇu Berubah dari subsetmenjadi extension. Terima kasih untuk umpan baliknya.
spocot
skor untuk ditulis dalam aliran otak adalah ide yang buruk - brainfuck adalah bagian dari aliran otak, oleh karena itu setiap program brainfuck adalah program aliran otak. itu seperti mengatakan program c ++ akan skor lebih baik daripada program C. OK, program C saya adalah program C ++, soo ....
pseudonym117
1
Mengapa menulis implementasi di Brainfuck memiliki manfaat lebih kecil daripada menulis implementasi di Brainflow? Sepertinya yang pertama akan lebih menantang, karena bahasa yang lebih kecil.
Peter Olson

Jawaban:

7

Perl - 233 230 210 182 180 176 174 171 byte

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

Cukup ambil juru bahasa BrainFuck saya yang ada, pindahkan, dan tambahkan fungsi BrainFlow.

Pembaruan: Benar-benar merestrukturisasi program untuk kehilangan 28 byte.

malkaroee
sumber
Perhatikan bahwa jika Anda diberi string 300 "+", Anda akan mendapatkan nilai yang tidak valid. Anda perlu melakukan% sanity check setelah / saat mengatur banyak dari nilai-nilai itu.
user0721090601
Saya pikir ini tidak bekerja dengan loop ( []). Anda tidak dapat mengevaluasi karakter demi karakter untuk itu.
nutki
Bagaimana nilai tambah diterjemahkan kembali ke dalam tanda kurung?
nutki
6

Mari mulai pesta ini.

C - 408 384 393 390 380 357 352 byte (masih terkikis)

Kompilasi dengan gccpada sistem yang mendukung POSIX. Argumen pertama adalah nama file yang berisi kode Brainflow untuk ditafsirkan. Baris baru ditambahkan untuk meningkatkan keterbacaan.

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

Dan versi yang ungolfed jika Anda tertarik. Beri tahu saya jika Anda melihat ada bug.

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

Pembaruan:

  • Terima kasih atas umpan balik awal yang memungkinkan saya untuk mematikan 24 byte tambahan.

  • Masuk bug diperbaiki. Menambahkan 9 byte lagi.

  • Menyimpan 3 byte per saran dari es1024.

  • Menyimpan 10 byte lagi per saran lainnya dari es1024.

  • Baru ingat bahwa variabel global diinisialisasi ke 0. Beralih dari ketakutan dan membuka untuk membaca dan membuka. Disimpan 23 byte.

  • Tidak perlu mengatur terminator nol pada program karena buffer sudah diinisialisasi ke nol. Disimpan 5 byte.
Orby
sumber
2
Saya pikir if () dan the; dapat diganti dengan?: dan menyimpan beberapa karakter.
Jerry Jeremiah
2
Literal karakter dapat diganti dengan ASCII yang setara untuk menyimpan karakter.
pseudonym117
1
@Orby Tampaknya tidak memproses karakter input dengan benar. Itu harus mengonversikan mereka ke representasi ascii dan menyimpannya. Selain itu berfungsi.
spocot
1
Anda dapat mengganti main(int c,char**v){dengan main(c,v)char**v;{dan menyimpan dua byte, serta pindah int i=0,p=0,b[9999],*k=b;ke luar fungsi, dan jatuhkan int untuk menyimpan empat byte. if (c==91)juga memiliki ruang yang tidak perlu.
es1024
1
Anda juga dapat mengganti sebagian besar jika tidak semuanya c==[number]?[action]:0;dengan c-[number]||[action]. ( c-[number]setara dengan c != [number]dan if(p)p--;denganp&&p--;
es1024
6

AppleScript 972 670

Sebagian besar bermain golf meskipun tidak mungkin menang. Saya tidak tahu mengapa saya tidak berpikir tentang hanya membangun skrip seperti perl yang dilakukan (meskipun masih tidak akan menang haha). Ini mungkin bisa golf lebih banyak dengan menyesuaikan kembali bagaimana nilai indeks sedikit lebih baik, AppleScript frustasi (untuk jenis barang) bahasa indeks 1.

Cukup berikan kode BrainFlow ke e (). Perhatikan bahwa perintah ASCII AppleScript menggunakan pengkodean MacOSRoman, jadi sementara output akan tampak berbeda, itu benar melihat representasi binernya. Anda harus memperhitungkannya saat memasukkan karakter ASCII atas dengan perintah ",".

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

(karena apa dengan otak Anda lebih dari menulis penerjemah brainfuck / flow dalam bahasa lain yang terlalu banyak berhubungan dengan kepala Anda?

pengguna0721090601
sumber