Menempatkan satu tip per jawaban akan menjadi terlalu banyak jawaban.
Belajar berpikir di Brainfuck. Ini sangat berbeda dari yang lainnya. Baca dan tulis, dan tulis ulang, dan tulis ulang banyak program brainfuck. Bahasa ini tidak memberi Anda banyak hal untuk dikerjakan, jadi penting untuk menggunakan apa yang diberikannya secara fleksibel dan efisien. Jangan biarkan abstraksi apa pun terjadi antara Anda dan bahasa - masuklah ke sana dan bergulat dengannya.
Dapatkan sangat nyaman dengan kontrol aliran tidak rusak. Untuk keluar dari loop keputusan, daripada mem-nolkan sel awal dengan menyalinnya di tempat lain dan kemudian menyalinnya kembali setelah meninggalkan loop, sering kali lebih baik untuk memindahkan pointer ke nol yang sudah ada di dekatnya. Ya, ini berarti pointer akan berada di tempat yang berbeda tergantung pada apakah Anda melewati loop, tetapi itu juga berarti tempat-tempat itu mungkin memiliki pengaturan yang berbeda dari nol di dekatnya dan nonzeros, yang dapat Anda gunakan untuk menyinkronkan ulang lokasi pointer menggunakan loop lain. Teknik ini sangat mendasar untuk pemrograman Brainfuck yang baik, dan berbagai bentuknya akan terus terbukti bermanfaat.
Itu dan fakta bahwa setiap >
atau <
biaya berarti bahwa rincian tata letak memori itu penting. Cobalah variasi tata letak sebanyak yang Anda sabar. Dan ingat, tata letak memori Anda tidak harus menjadi pemetaan data yang kaku ke lokasi. Itu bisa berubah selama eksekusi.
Pada skala yang lebih besar, pertimbangkan dan bahkan coba terapkan berbagai algoritma yang berbeda. Awalnya tidak akan jelas algoritma apa yang terbaik; bahkan mungkin tidak jelas pendekatan dasar apa yang terbaik, dan mungkin akan menjadi sesuatu yang berbeda dari apa yang terbaik dalam bahasa normal.
Jika Anda berurusan dengan data berukuran besar atau variabel, lihat apakah ada cara Anda dapat mengatasinya secara lokal, tanpa harus melacak seberapa besar itu atau lokasi numerik Anda di dalamnya.
Data yang sama dapat menjadi dua hal yang berbeda. (Paling sering, angka atau karakter dan juga penanda posisi bukan nol. Tapi lihat acak.b , di mana penghitung bit berfungsi ganda sebagai nilai satu sel otomat seluler).
Kode yang sama dapat melakukan dua hal yang berbeda, dan jauh lebih mudah untuk membuatnya dalam bahasa di mana kode tersebut sama generiknya <+<
. Waspadai kemungkinan seperti itu. Bahkan, kadang-kadang Anda mungkin memperhatikan, bahkan dalam apa yang tampaknya merupakan program yang ditulis dengan baik, bahwa ada bagian-bagian kecil yang dapat dihapus seluruhnya, tidak ada yang ditambahkan, dan masalahnya, secara kebetulan, masih berjalan dengan sempurna.
Dalam sebagian besar bahasa, Anda sering menggunakan kompiler atau juru bahasa untuk memeriksa perilaku program Anda. Bahasa Brainfuck menuntut kontrol konseptual yang lebih besar; jika Anda memerlukan kompiler untuk memberi tahu Anda apa yang dilakukan program Anda, Anda tidak memiliki pemahaman yang cukup tentang program Anda, dan Anda mungkin perlu menatapnya lagi - setidaknya jika Anda ingin memiliki gambar yang cukup jelas tentang halo konseptual dari program serupa untuk menjadi pandai golf. Dengan latihan, Anda akan menghasilkan selusin versi program Anda sebelum Anda mencoba menjalankannya, dan pada saat itu Anda akan 95% yakin bahwa versi terpendek Anda akan berjalan dengan benar.
Semoga berhasil! Sangat sedikit orang yang bersusah payah menulis Brainfuck secara ringkas, tetapi saya pikir itulah satu-satunya cara bahasa tersebut dapat membenarkan perhatian yang berkelanjutan - sebagai bentuk seni yang sangat tidak dikenal.
Beberapa tips di sini:
Konstanta:
Halaman konstanta The Esolangs memiliki daftar yang sangat berguna satu cara terpendek untuk membuat nilai-nilai tertentu. Saya mendapati diri saya membaca halaman ini setidaknya dua kali per program.
Awal dari segalanya:
Ini mengatur rekaman dalam format 3 * n ^ 2, yang terlihat seperti
3 6 12 24 48 96 192 128 0 0 '
Mengapa ini sangat penting?
Mari kita lihat daftarnya:
0
a
A
.Dari algoritma yang satu ini, kita berada di awal hampir setiap urutan dalam rentang ASCII, bersama dengan penghitung untuk masing-masing dan baris baru yang mudah dijangkau.
Contoh praktis:
Mencetak semua huruf besar dan kecil dan angka.
Dengan algoritma:
Tanpa:
Kami menghabiskan sebagian besar byte hanya menginisialisasi rekaman pada contoh kedua. Beberapa di antaranya diimbangi oleh gerakan ekstra pada contoh pertama, tetapi metode ini jelas memiliki keunggulan.
Beberapa algoritma menarik lainnya dalam nada yang sama:
3 * 2 ^ n + 1:
Ini mengimbangi nilai dengan 1, yang mencapai beberapa hal. Itu membuat 12 carriage return, 64 awal yang sebenarnya dari huruf besar, dan 24 yang lebih dekat ke 26.
2 ^ n:
Karena 64 baik untuk huruf besar, 32 adalah ASCII untuk spasi, dan 128 dapat digunakan sebagai penghitung untuk 26 (130/5 = 26). Ini dapat menghemat byte dalam situasi tertentu di mana angka dan huruf kecil tidak diperlukan.
Pilih implementasi yang sesuai dengan pertanyaan:
+[[-<+>>+>+<<]>]
), atau memproses angka yang lebih besar / negatif. The downside adalah bahwa beberapa metode umum, seperti[-]
dan[->+<]
tidak dapat diandalkan, kalau-kalau jumlahnya negatif.Pantau apa yang terjadi:
Setiap saat Anda harus memiliki komentar tentang di mana pointer harus berada dalam kaitannya dengan data di sekitarnya, dan pastikan bahwa Anda mengetahui kisaran nilai yang mungkin dari setiap sel. Ini sangat penting ketika Anda telah membagi pointer sebelum loop, karena Anda ingin menggabungkan dua kemungkinan kembali bersama setelahnya.
Pada titik mana pun, kode saya dipenuhi dengan komentar di setiap baris lain yang terlihat seperti ini:
Beberapa saran tambahan adalah memberikan simbol makna khusus. Dalam contoh di atas,
'
adalah di mana pointer berada,*
berarti pengulangan dalam arah itu,?
berarti sel dengan nilai yang tidak diketahui,!0
berarti sel non-nol,_
adalah pengganti-
danp
merupakan pengganti+
.or
menyiratkan bahwa rekaman itu bisa terlihat seperti representasi, dan perlu ditangani seperti itu.Skema simbol Anda tidak harus sama dengan skema saya (yang memiliki beberapa kekurangan), tetapi harus konsisten. Ini juga sangat berguna ketika men-debug, karena Anda dapat menjalankannya sampai titik itu dan membandingkan rekaman aktual dengan apa yang seharusnya Anda miliki, yang dapat menunjukkan kelemahan potensial dalam kode Anda.
sumber
Saran utama saya adalah jangan.
OKE, baiklah, Anda menginginkan sesuatu yang lebih berguna dari itu. BF sudah merupakan bahasa yang sangat singkat, tetapi yang benar-benar membunuh Anda adalah aritmatika, yang secara efektif perlu dilakukan secara unary. Sebaiknya baca halaman konstanta di Esolang untuk memilih cara menulis angka besar secara efisien, dan mengeksploitasi pembungkus jika memungkinkan.
Akses memori juga sangat mahal. Karena Anda membaca dari kaset, Anda harus mengingat di mana kepala Anda bergerak pada waktu tertentu. Tidak seperti bahasa lain di mana Anda bisa hanya menulis
a
,b
,c
, di bf Anda harus secara eksplisit memindahkan kepala beberapa jumlah byte kiri atau kanan, sehingga Anda harus memperhatikan di mana Anda menyimpan apa. Saya cukup yakin bahwa mengatur memori Anda secara optimal adalah NP-hard, jadi semoga sukses dengan yang itu.sumber
Dalam jawaban ini saya akan merujuk ke sel khusus pada rekaman itu berkali-kali. Tidak masalah sel yang mana, tetapi sel yang sama di seluruh jawaban. Untuk keperluan posting ini, saya akan memanggil sel itu "Todd".
Saat mencoba menyetel sel ke nilai konstan, terkadang membayar untuk tidak menyelesaikannya segera. Misalnya, Anda ingin Todd mengandung 30. Kemudian dalam kode Anda (yang dapat mengubah nilai Todd tetapi tidak pernah membacanya), Anda kembali ke Todd. Jika nilai Todd adalah 0, program keluar. Jika tidak, nilai Todd dicetak selamanya.
Menurut halaman esolangs.org dari konstanta brainfuck (yang mungkin bisa menjadi subjek tip sendiri!) Cara terpendek untuk mendapatkan 30 adalah
>+[--[<]>>+<-]>+
. Yang memimpin>
hanya ada di sana untuk memastikan bahwa tidak ada di sebelah kiri pointer yang dimodifikasi, tetapi dalam hal ini kita akan menganggap kita tidak peduli tentang itu dan menjatuhkannya. Menggunakan kode itu, kode Anda akan terlihat seperti ini:Anda dapat memikirkan potongan kode pertama seperti ini:
Tapi ingat dua karakter terakhir dalam chunk bahwa:
>+
. Sama validnya untuk berpikir seperti ini:Perhatikan bahwa Anda
(GO TO TODD)
dua kali! Anda bisa menulis kode seperti ini:Dengan asumsi bahwa jumlah byte yang diperlukan
(GO TO TODD)
sama dengan sebelumnya, satu langkah lebih sedikit == satu byte lebih sedikit! Terkadang fakta bahwa posisi awal Anda telah berubah memang mengambil manfaat itu, tetapi tidak selalu.sumber
Tip kecil untuk tantangan tanpa input. Anda dapat menggunakan
,
alih-alih[-]
, jika Anda perlu membersihkan sel dengan cepat, karena sebagian besar penafsir (termasuk TIO.run satu) akan mengatur konten sel ke representasi EOF menjadi nol. Ini membuat program-program sedikit tidak dapat ditonton, tetapi siapa yang peduli dengan kode golf itu?sumber