Seseorang mengirimkan ini kepada saya dan mengklaim itu adalah halo dunia di Brainfuck (dan saya harap begitu ...)
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Saya tahu dasar-dasar cara kerjanya dengan memindahkan pointer dan increment dan mengurangi barang ...
Namun saya masih ingin tahu, bagaimana sebenarnya cara kerjanya? Bagaimana cara mencetak sesuatu di layar pada awalnya? Bagaimana cara menyandikan teks? Saya tidak mengerti sama sekali ...
brainfuck
esoteric-languages
speeder
sumber
sumber
Jawaban:
1. Dasar-dasar
Untuk memahami Brainfuck, Anda harus membayangkan deretan sel tak terbatas yang diinisialisasi oleh
0
masing-masing sel .Saat program brainfuck dimulai, itu menunjuk ke sel mana saja.
Jika Anda memindahkan penunjuk ke kanan,
>
Anda memindahkan penunjuk dari sel X ke sel X + 1Jika Anda meningkatkan nilai sel,
+
Anda mendapatkan:Jika Anda meningkatkan nilai sel lagi,
+
Anda mendapatkan:Jika Anda menurunkan nilai sel,
-
Anda mendapatkan:Jika Anda memindahkan penunjuk ke kiri,
<
Anda memindahkan penunjuk dari sel X ke sel X-12. Masukan
Untuk membaca karakter Anda menggunakan koma
,
. Apa yang dilakukannya adalah: Membaca karakter dari input standar dan menulis kode ASCII desimalnya ke sel yang sebenarnya.Lihat tabel ASCII . Misalnya, kode desimal
!
is33
, whilea
is97
.Nah, bayangkan memori program BF Anda terlihat seperti:
Dengan asumsi input standar singkatan
a
, jika Anda menggunakan,
operator koma , yang dilakukan BF adalah membacaa
kode ASCII desimal97
ke memori:Anda biasanya ingin berpikir seperti itu, namun kenyataannya sedikit lebih kompleks. Sebenarnya BF tidak membaca karakter tapi byte (apapun byte itu). Mari saya tunjukkan contoh:
Di linux
cetakan:
yang merupakan karakter Polandia tertentu. Karakter ini tidak dikodekan oleh pengkodean ASCII. Dalam hal ini adalah pengkodean UTF-8, jadi biasanya memakan waktu lebih dari satu byte dalam memori komputer. Kami dapat membuktikannya dengan membuat dump heksadesimal:
yang menunjukkan:
Angka nol diimbangi.
82
adalah yang pertama danc5
mewakili byte keduał
(agar kita akan membacanya).|..|
adalah representasi grafis yang tidak dimungkinkan dalam kasus ini.Nah, jika Anda mengirimkan
ł
sebagai masukan ke program BF Anda yang membaca satu byte, memori program akan terlihat seperti:Kenapa
197
? Nah197
desimal adalahc5
heksadesimal. Tampak akrab? Tentu saja. Ini byte pertama darił
!3. Keluaran
Untuk mencetak karakter Anda menggunakan titik
.
Apa yang dilakukannya adalah: Dengan asumsi kita memperlakukan nilai sel aktual seperti kode ASCII desimal, mencetak karakter yang sesuai dengan keluaran standar.Nah, bayangkan memori program BF Anda terlihat seperti:
Jika Anda menggunakan operator titik (.) Sekarang, yang dilakukan BF adalah mencetak:
Karena
a
kode desimal di ASCII adalah97
.Jadi misal program BF seperti ini (97 plus 2 titik):
Akan meningkatkan nilai sel yang ditunjuknya hingga 97 dan mencetaknya 2 kali.
4. Perulangan
Dalam BF loop terdiri dari loop begin
[
dan loop end]
. Anda bisa menganggapnya seperti saat berada di C / C ++ di mana kondisinya adalah nilai sel sebenarnya.Lihat program BF di bawah ini:
++
menambah nilai sel sebenarnya dua kali:Dan
[]
sepertiwhile(2) {}
, jadi ini putaran tak terbatas.Katakanlah kita tidak ingin putaran ini tidak terbatas. Kita bisa lakukan misalnya:
Jadi setiap kali loop loop itu menurunkan nilai sel yang sebenarnya. Setelah nilai sel sebenarnya adalah
0
loop berakhir:Mari kita pertimbangkan contoh lain dari loop terbatas:
Contoh ini menunjukkan, kita belum menyelesaikan loop di sel tempat loop dimulai:
Bagaimanapun juga merupakan praktik yang baik untuk mengakhiri dari mana kita memulai. Kenapa? Karena jika loop mengakhiri sel lain itu dimulai, kita tidak bisa berasumsi di mana penunjuk sel akan berada. Sejujurnya, praktik ini mengurangi brainfuck.
sumber
Wikipedia memiliki versi kode yang diberi komentar.
Untuk menjawab pertanyaan Anda, karakter
,
dan.
digunakan untuk I / O. Teksnya adalah ASCII.The Wikipedia Artikel yang terjadi di beberapa lebih mendalam, juga.
sumber
,
dan.
digunakan untuk I / O, seperti C print dengan menggunakanputchar
. Ini adalah detail implementasi yang ditangani oleh kompilator.Untuk menjawab pertanyaan bagaimana ia tahu apa yang harus dicetak, saya telah menambahkan kalkulasi nilai ASCII di sebelah kanan kode tempat pencetakan terjadi:
sumber
Brainfuck sama seperti namanya. Ini hanya menggunakan 8 karakter
> [ . ] , - +
yang menjadikannya bahasa pemrograman tercepat untuk dipelajari tetapi paling sulit untuk diterapkan dan dipahami. … .Dan membuat Anda akhirnya berakhir dengan mengacaukan otak Anda.Ini menyimpan nilai dalam array: [72] [101] [108] [111]
let, awalnya pointer menunjuk ke sel 1 dari array:
>
pindahkan penunjuk ke kanan sebanyak 1<
pindahkan penunjuk ke kiri sebesar 1+
menambah nilai sel sebesar 1-
menambah nilai elemen sebesar 1.
nilai cetak sel saat ini.,
mengambil masukan ke sel saat ini.[ ]
loop, +++ [-] penghitung 3 hitungan bcz memiliki 3 '+' sebelumnya, dan - mengurangi variabel hitungan dengan 1 nilai.nilai yang disimpan dalam sel adalah nilai ascii:
jadi mengacu pada larik di atas: [72] [101] [108] [108] [111] jika Anda cocok dengan nilai ascii Anda akan menemukan bahwa itu adalah Hello writtern
Selamat! Anda telah mempelajari sintaks BF
——- Sesuatu yang lebih ———
mari kita buat program pertama kita yaitu Hello World , setelah itu Anda bisa menuliskan nama Anda dalam bahasa ini.
pecah menjadi beberapa bagian:
Membuat array dari 4 sel (jumlah>) dan menetapkan penghitung 10 sesuatu seperti: —-psuedo code—-
karena nilai counter disimpan di cell 0 dan> pindah ke cell 1 update nilainya dengan + 7> pindah ke cell 2 selisih 10 ke nilai sebelumnya dan seterusnya….
<<<
kembali ke sel 0 dan mengurangi nilainya dengan 1maka setelah penyelesaian loop kita memiliki array: [70,100,30,10]
berpindah ke elemen pertama dan menambah nilainya dengan 2 (dua '+') dan kemudian mencetak karakter ('.') dengan nilai ascii tersebut. yaitu misalnya di python: chr (70 + 2) # cetakan 'H'
pindah ke sel ke-2 selisih 1 ke nilainya 100 + 1 dan mencetak ('.') nilainya yaitu chr (101) chr (101) #prints 'e' sekarang tidak ada> atau <di bagian berikutnya sehingga mengambil nilai sekarang dari elemen terbaru dan kenaikannya saja
elemen terbaru = 101 oleh karena itu, 101 + 7 dan mencetaknya dua kali (karena ada dua '..') chr (108) #prints l dua kali dapat digunakan sebagai
——— Dimana itu digunakan? ——-
Ini hanyalah bahasa lelucon yang dibuat untuk menantang pemrogram dan tidak digunakan secara praktis di mana pun.
sumber
Semua jawaban lengkap, tapi kurang satu detail kecil: Pencetakan. Dalam membangun penerjemah brainfuck, Anda juga mempertimbangkan karakternya
.
, seperti inilah sebenarnya tampilan printing statement di brainfuck. Jadi apa yang harus dilakukan penerjemah brainfuck Anda adalah, setiap kali ia menemukan.
karakter itu mencetak byte yang saat ini menunjuk.Contoh:
misalkan Anda memiliki ->
char *ptr = [0] [0] [0] [97] [0]
... jika ini adalah pernyataan brainfuck:>>>.
penunjuk Anda harus dipindahkan 3 spasi ke kanan mendarat di:,[97]
jadi sekarang*ptr = 97
, setelah melakukan itu penerjemah Anda menemukan a.
, itu kemudian harus memanggilatau pernyataan pencetakan yang setara untuk mencetak byte yang saat ini menunjuk, yang memiliki nilai 97 dan huruf
a
kemudian akan dicetak padastd_output
.sumber
Saya pikir yang Anda tanyakan adalah bagaimana Brainfuck tahu apa yang harus dilakukan dengan semua kode. Ada pengurai yang ditulis dalam bahasa tingkat yang lebih tinggi seperti Python untuk menafsirkan arti titik, atau arti tanda tambahan dalam kode.
Jadi parser akan membaca kode Anda baris demi baris, dan mengatakan oke ada simbol> jadi saya harus memajukan lokasi memori, kodenya sederhana, jika (isi di lokasi memori itu) ==>, memlocation = + memlocation yang mana ditulis dalam bahasa tingkat yang lebih tinggi, demikian pula jika (konten di lokasi memori) == ".", lalu cetak (konten lokasi memori).
Semoga ini menyelesaikannya. tc
sumber