Hexagony , 920 722 271 byte
Enam jenis buah loop, menurut Anda? Untuk itulah Hexagony dibuat .
){r''o{{y\p''b{{g''<.{</"&~"&~"&<_.>/{.\.....~..&.>}<.._...=.>\<=..}.|>'%<}|\.._\..>....\.}.><.|\{{*<.>,<.>/.\}/.>...\'/../==.|....|./".<_>){{<\....._>\'=.|.....>{>)<._\....<..\..=.._/}\~><.|.....>e''\.<.}\{{\|./<../e;*\.@=_.~><.>{}<><;.(~.__..>\._..>'"n{{<>{<...="<.>../
Oke, tidak. Ya Tuhan, apa yang saya lakukan pada diri saya sendiri ...
Kode ini sekarang merupakan segi enam dengan panjang sisi 10 (dimulai pada 19). Mungkin bisa di-golf lagi, mungkin bahkan sampai ukuran 9, tapi saya pikir pekerjaan saya selesai di sini ... Untuk referensi, ada 175 perintah aktual di sumbernya, banyak di antaranya berpotensi mirror yang tidak perlu (atau ditambahkan untuk membatalkan perintah dari persimpangan jalan).
Terlepas dari linearitas yang tampak, kode ini sebenarnya dua dimensi: Hexagony akan mengatur ulang menjadi segi enam reguler (yang juga merupakan kode yang valid, tetapi semua spasi putih adalah opsional dalam Hexagony). Berikut adalah kode yang tidak dilipat dalam semua ... yah saya tidak ingin mengatakan "cantik":
) { r ' ' o { { y \
p ' ' b { { g ' ' < .
{ < / " & ~ " & ~ " & <
_ . > / { . \ . . . . . ~
. . & . > } < . . _ . . . =
. > \ < = . . } . | > ' % < }
| \ . . _ \ . . > . . . . \ . }
. > < . | \ { { * < . > , < . > /
. \ } / . > . . . \ ' / . . / = = .
| . . . . | . / " . < _ > ) { { < \ .
. . . . _ > \ ' = . | . . . . . > {
> ) < . _ \ . . . . < . . \ . . =
. . _ / } \ ~ > < . | . . . . .
> e ' ' \ . < . } \ { { \ | .
/ < . . / e ; * \ . @ = _ .
~ > < . > { } < > < ; . (
~ . _ _ . . > \ . _ . .
> ' " n { { < > { < .
. . = " < . > . . /
Penjelasan
Saya bahkan tidak akan mencoba dan mulai menjelaskan semua jalur eksekusi yang berbelit-belit dalam versi golf ini, tetapi algoritme dan alur kontrol keseluruhannya identik dengan versi yang tidak diklik ini yang mungkin lebih mudah dipelajari untuk orang yang benar-benar penasaran setelah saya menjelaskan algoritme:
) { r ' ' o { { \ / ' ' p { . . .
. . . . . . . . y . b . . . . . . .
. . . . . . . . ' . . { . . . . . . .
. . . . . . . . \ ' g { / . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . > . . . . < . . . . . . . . .
. . . . . . . . . . . . . . > . . ) < . . . . .
. . . . . . . . . . / = { { < . . . . ( . . . . .
. . . . . . . . . . . ; . . . > . . . . . . . . . <
. . . . . . . . . . . . > < . / e ; * \ . . . . . . .
. . . . . . . . . . . . @ . } . > { } < . . | . . . . .
. . . . . / } \ . . . . . . . > < . . . > { < . . . . . .
. . . . . . > < . . . . . . . . . . . . . . . | . . . . . .
. . . . . . . . _ . . > . . \ \ " ' / . . . . . . . . . . . .
. . . . . . \ { { \ . . . > < . . > . . . . \ . . . . . . . . .
. < . . . . . . . * . . . { . > { } n = { { < . . . / { . \ . . |
. > { { ) < . . ' . . . { . \ ' < . . . . . _ . . . > } < . . .
| . . . . > , < . . . e . . . . . . . . . . . . . = . . } . .
. . . . . . . > ' % < . . . . . . . . . . . . . & . . . | .
. . . . _ . . } . . > } } = ~ & " ~ & " ~ & " < . . . . .
. . . \ . . < . . . . . . . . . . . . . . . . } . . . .
. \ . . . . . . . . . . . . . . . . . . . . . . . < .
. . . . | . . . . . . . . . . . . . . . . . . = . .
. . . . . . \ . . . . . . . . . . . . . . . . / .
. . . . . . > . . . . . . . . . . . . . . . . <
. . . . . . . . . . . . . . . . . . . . . . .
_ . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
Jujur saja, di paragraf pertama aku hanya setengah bercanda. Fakta bahwa kita sedang berurusan dengan siklus enam elemen sebenarnya sangat membantu. Model memori Hexagony adalah kisi heksagonal tak terbatas di mana setiap tepi kisi berisi integer presisi sewenang-wenang yang ditandatangani, diinisialisasi ke nol.
Berikut adalah diagram tata letak memori yang saya gunakan dalam program ini:
Bit lurus panjang di sebelah kiri digunakan sebagai string diakhiri 0 dengan a
ukuran sewenang-wenang yang dikaitkan dengan huruf r . Garis putus-putus pada huruf-huruf lain mewakili jenis struktur yang sama, masing-masing diputar 60 derajat. Awalnya, penunjuk memori menunjuk pada tepi berlabel 1 , menghadap ke utara.
Bit linier pertama dari kode mengatur "bintang" tepi pada huruf-huruf roygbp
serta mengatur tepi awal 1
, sehingga kita tahu di mana siklus berakhir / dimulai (antara p
dan r
):
){r''o{{y''g{{b''p{
Setelah ini, kita kembali ke tepi berlabel 1 .
Sekarang ide umum dari algoritma ini adalah ini:
- Untuk setiap huruf dalam siklus, terus membaca surat dari STDIN dan, jika berbeda dari surat saat ini, tambahkan ke string yang terkait dengan surat itu.
- Ketika kita membaca surat yang sedang kita cari, kita menyimpan huruf
e
tepi yang berlabel ? , karena selama siklus tidak lengkap, kita harus mengasumsikan bahwa kita harus memakan karakter ini juga. Setelah itu, kami akan bergerak di sekitar cincin ke karakter berikutnya dalam siklus.
- Ada dua cara proses ini dapat terganggu:
- Entah kita sudah menyelesaikan siklus. Dalam hal ini, kami melakukan putaran cepat melalui siklus, menggantikan semua yang ada
e
dalam ? tepi dengan n
s, karena sekarang kami ingin siklus yang tetap pada kalung itu. Kemudian kita beralih ke kode pencetakan.
- Atau kami menekan EOF (yang kami kenali sebagai kode karakter negatif). Dalam hal ini, kami menulis nilai negatif ke dalam ? tepi karakter saat ini (sehingga kita dapat dengan mudah membedakannya dari keduanya
e
dan n
). Kemudian kami mencari tepi 1 (untuk melewati sisa siklus yang berpotensi tidak lengkap) sebelum pindah ke kode pencetakan juga.
- Kode pencetakan melewati siklus lagi: untuk setiap karakter dalam siklus itu membersihkan string yang disimpan saat mencetak
e
untuk setiap karakter. Lalu pindah ke ? edge terkait dengan karakter. Jika negatif, kami cukup menghentikan program. Jika positif, kami cukup mencetaknya dan beralih ke karakter berikutnya. Setelah kami menyelesaikan siklus, kami kembali ke langkah 2.
Hal lain yang mungkin menarik adalah bagaimana saya menerapkan string ukuran sewenang-wenang (karena ini adalah pertama kalinya saya menggunakan memori tidak terbatas dalam Hexagony).
Bayangkan kami di beberapa titik di mana kita masih membaca karakter untuk r (sehingga kita dapat menggunakan diagram seperti) dan sebuah [0] dan sebuah 1 telah diisi dengan karakter (segala sesuatu utara-barat dari mereka masih nol ). Misalnya mungkin kita baru saja membaca dua karakter pertama og
dari input ke tepi itu dan sekarang sedang membaca a y
.
Karakter baru dibaca ke dalam tepi. Kami menggunakan ? edge untuk memeriksa apakah karakter ini sama dengan r
. (Ada trik yang bagus di sini: Hexagony hanya dapat membedakan antara positif dan non-positif dengan mudah, jadi memeriksa kesetaraan melalui pengurangan itu menjengkelkan dan membutuhkan setidaknya dua cabang. Tetapi semua huruf kurang dari faktor 2 dari satu sama lain, jadi kita dapat membandingkan nilai dengan mengambil modulo, yang hanya akan memberikan nol jika sama.)
Karena y
berbeda dari r
, kami memindahkan (unlabelled) tepi kiri di dan salin y
sana. Kita sekarang bergerak lebih jauh di sekitar segi enam, menyalin karakter salah satu ujung lanjut setiap kali, sampai kami memiliki y
di seberang tepi di . Tapi sekarang sudah ada karakter dalam [0] yang tidak ingin kita timpa. Sebaliknya, kita "drag" yang y
sekitar segi enam berikutnya dan memeriksa sebuah 1 . Tapi ada karakter di sana juga, jadi kita pergi segi enam lebih jauh. Sekarang [2] masih nol, jadi kami saliny
ke dalamnya. Penunjuk memori sekarang bergerak kembali di sepanjang tali menuju cincin bagian dalam. Kita tahu kapan kita telah mencapai awal string, karena tepi (tidak berlabel) antara a [i] semuanya nol sedangkan ? positif.
Ini mungkin akan menjadi teknik yang berguna untuk menulis kode non-sepele dalam Hexagony secara umum.