2.}<@>%?<{>$"/\M!8;
Dapat dibaca:
2 . }
< @ > %
? < { > $
" / \ M
! 8 ;
Cobalah online!
Ini mungkin bisa di-golf dengan satu atau dua byte, tetapi itu mungkin memerlukan beberapa tata letak yang benar-benar cerdik, yang mungkin lebih mudah ditemukan melalui brute force (bahkan jika mungkin butuh waktu agak lama untuk menemukannya).
Penjelasan tingkat tinggi
Program ini sebagian besar mengikuti kodesemu ini:
while (read number is not zero)
{
if (number is even)
print number;
}
Yang menyalahgunakan bagaimana Hexagony mencoba membaca angka begitu STDIN kosong (mengembalikan nol). Terima kasih banyak untuk Martin atas bantuannya dalam pendekatan ini.
Penjelasan Lengkap
Saya masih belum mengutak-atik Mono untuk menjalankan IDE esoterik fantastis Timwi , jadi saya mencondongkan tubuh ke Martin untuk memberi saya beberapa gambar cantik yang membantu!
Pertama, sedikit primer pada aliran kontrol dasar dalam Hexagony. Pointer instruksi pertama (IP), yang merupakan satu-satunya yang digunakan dalam program ini, dimulai di kiri atas kode sumber heksagonal, dan mulai bergerak ke arah kanan. Setiap kali IP meninggalkan tepi segi enam, itu bergerak side_length - 1
baris menuju tengah segi enam. Karena program ini menggunakan panjang sisi tiga segi enam, IP akan selalu bergerak dua baris ketika ini terjadi. Satu-satunya pengecualian adalah jika bergerak dari baris tengah, di mana ia bergerak menuju bagian atas atau bawah hexagon, tergantung pada nilai dari tepi memori saat ini.
Sekarang sedikit tentang persyaratan. Satu-satunya persyaratan dalam Hexagony untuk aliran kontrol adalah >
, <
dan tepi tengah hexagon. Ini semua mengikuti aturan konstan: jika nilai pada tepi memori saat ini adalah nol atau aliran kontrol negatif bergerak ke kiri dan jika positif kontrol mengalir ke kanan. Lebih besar dari dan kurang dari tanda kurung mengarahkan IP pada sudut enam puluh derajat, sedangkan tepi segi enam mengontrol ke mana baris IP melompat.
Hexagony juga memiliki model memori khusus, di mana semua data disimpan di tepi grid heksagonal yang tak terbatas. Program ini hanya menggunakan tiga sisi: satu untuk menyimpan dua, satu untuk nomor yang sedang dibaca, dan satu untuk nomor modulo dua. Itu terlihat seperti:
Mod \ / Input
|
2
Saya tidak akan menjelaskan dengan hati-hati di mana kita berada di memori pada setiap titik selama penjelasan program, jadi kembali ke sini jika Anda bingung dengan di mana kita berada dalam memori.
Dengan semua itu, penjelasan sebenarnya bisa dimulai. Pertama, kita mengisi tepi "2" dalam memori dengan angka 2, lalu kita jalankan perintah no-op dan pindahkan penunjuk memori ke kanan ( 2.}
).
Selanjutnya, kita mulai loop program utama. Kami membaca angka pertama dari STDIN dan kemudian kami menekan conditional ( ?<
). Jika tidak ada angka yang tersisa di STDIN, ini membaca nol ke tepi memori saat ini, jadi kami belok kiri ke @
, yang mengakhiri program. Kalau tidak, kita pantulkan cermin, pindahkan penunjuk memori ke belakang dan ke kiri, bungkus sekitar segi enam untuk menghitung sisa membagi input dengan 2 dan kemudian tekan kondisional lain ( /"%>
).
Jika sisanya adalah satu (yaitu angkanya ganjil), kita belok kanan mengikuti jalur biru di atas dimulai dengan mengeksekusi no-op lagi, lalu kita lilitkan ke bagian bawah segi enam, kalikan tepi saat ini dengan 10 dan kemudian tambahkan delapan, bangkit dari beberapa mirror, lakukan penggandaan dan penambahan yang sama lagi, dapatkan 188 di tepi saat ini, membungkus kembali ke atas segi enam, menjalankan no-op lagi, dan akhirnya mengakhiri program ( .8/\8.@
). Hasil berbelit-belit ini adalah kecelakaan yang membahagiakan, saya awalnya telah menulis sedikit logika yang lebih sederhana, tetapi memperhatikan bahwa saya dapat menghapusnya demi no-op, yang saya pikir lebih sesuai dengan semangat Hexagony.
Jika sisanya nol kita sebaliknya belok kiri mengikuti jalan merah, di atas. Ini menyebabkan kita untuk memindahkan penunjuk memori ke kiri, dan kemudian mencetak nilai di sana (nilai input) sebagai angka. Cermin yang kita temui bertindak sebagai no-op karena arah yang kita bergerak ( {/!
). Lalu kami mencapai ujung hexagon yang bertindak bersyarat dengan hanya satu hasil, karena nilai input dari sebelumnya sudah diuji menjadi positif, jadi kami selalu bergerak ke kanan (jika Anda membayangkan diri Anda menghadap ke arah IP) . Kami kemudian mengalikan input dengan 10 dan menambahkan dua, hanya untuk mengubah arah, membungkus dan menimpa nilai baru dengan nilai ascii dari huruf kapital M, 77. Kemudian kami menekan beberapa mirror, dan keluar melewati tepi tengah segi enam dengan trampolin (2<M\>$
). Karena 77 positif, kita bergerak ke arah bagian bawah segi enam dan karena trampolin lewati instruksi pertama ( !
). Kami kemudian mengalikan tepi memori saat ini dengan 10 dan menambahkan 8, mendapatkan 778. Kami kemudian menampilkan nilai ini mod 256 (10) sebagai karakter ASCII, yang kebetulan merupakan baris baru. Akhirnya kita keluar dari segi enam dan membungkus kembali ke yang pertama ?
yang menimpa 778 dengan nilai input berikutnya.