/o!
\i@/e)q&w[?'`-+k3-n
Cobalah online!
Input harus huruf kecil. Mencetak 1
untuk kata-kata dolar dan 0
sebaliknya.
Penjelasan
Saatnya memamerkan kaset Alice dan beberapa aliran kontrol lanjutan. Meskipun cukup baik dalam bekerja dengan bilangan bulat dan string secara individual, Alice tidak memiliki built-in untuk a) menentukan panjang string, b) mengkonversi antara karakter dan poin kode mereka. Alasan untuk ini adalah bahwa semua perintah Alice memetakan bilangan bulat ke bilangan bulat atau string ke string. Tetapi keduanya membutuhkan pemetaan string ke integer atau sebaliknya, sehingga mereka tidak cocok dengan salah satu mode Alice.
Namun, selain tumpukan itu, Alice juga memiliki kaset dan mode Kardinal dan Ordinal menginterpretasikan data pada rekaman dengan cara yang berbeda.
- Dalam mode Kardinal, ini adalah rekaman biasa yang akrab dari bahasa lain seperti Brainfuck. Anda dapat menyimpan satu bilangan bulat di setiap sel dan Anda bisa memindahkan kepala kaset. Rekaman itu panjang tak terhingga dan awalnya memegang -1 di setiap sel. Sel-sel juga diindeks dan kepala pita dimulai pada indeks 0 .
- Mode ordinal memiliki head tape sendiri (juga mulai dari indeks 0 ) dan menafsirkan tape sebagai daftar string. String diakhiri oleh sel non-karakter (yaitu nilai apa pun yang bukan titik kode Unicode yang valid), khususnya -1 . Jadi untuk mode Ordinal, rekaman itu awalnya diisi dengan string kosong.
Rekaman ini dapat digunakan untuk kedua operasi di atas: untuk mendapatkan panjang string, kita menulisnya ke rekaman dalam mode Ordinal, mencari terminating -1 dalam mode Kardinal dan mengambil posisi kepala tape. Untuk mengonversi karakter ke titik kode mereka, kami cukup membacanya dari rekaman dalam mode Kardinal.
Dua fitur penting lainnya yang digunakan dalam solusi ini adalah return stack dan iterator. Alice memiliki tumpukan kembali yang biasanya diisi saat menggunakan perintah lompat j
, dan Anda dapat memunculkan alamat untuk melompat kembali k
. Namun, juga memungkinkan untuk mendorong alamat saat ini ke tumpukan kembali tanpa melompat ke mana pun w
. Jika kita gabungkan w
dengan perintah repeat&
, kita bisa mendorong alamat saat ini ke stack kembali n kali. Sekarang setiap kali kami mencapai k
, satu salinan muncul dari tumpukan kembali dan kami melakukan iterasi lain dari w
(mulai di sel setelah itu, karena IP bergerak sebelum menjalankan perintah lain). Ketika tumpukan kembali menjadi kosong,k
tidak melakukan apa-apa dan IP hanya melewatinya. Karenanya &w...k
muncul bilangan bulat n dan kemudian jalankan ...
n + 1 kali, yang memberi kita cara yang sangat ringkas untuk mengekspresikan for
loop sederhana .
Ke kode itu sendiri ...
/ Reflect to SE. Switch to Ordinal.
i Read the input word as a string.
Bounce off bottom boundary, move NE.
! Store the input word on the tape.
Bounce off top boundary, move SE.
/ Reflect to E. Switch to Cardinal.
e Push -1.
) Seek right on the tape for a -1, which finds the -1 terminating
the input word.
q Push the tape head's position, which gives us the string length N.
&w Repeat this loop n+1 times (see above for an explanation)...
[ Move the tape head left by one cell.
? Retrieve the code point of the character in that cell.
'` Push 96.
- Subtract it from the code point to convert the letters to 1...26.
+ Add the result to a running total. This total is initialised to
zero, because in Cardinal mode, the stack is implicitly filled with
an infinite amount of zeros at the bottom.
k End of loop.
Note that the above loop ran once more than we have characters in the
string. This is actually really convenient, because it means that we've
added a "-1 character" to the running total. After subtracting 96 to
convert it to its "letter value" this gives 97. So dollar words will
actually result in 100 - 97 = 3, which we can check against for one
byte less than for equality with 100.
3- Subtract 3 to give 0 for dollar words.
n Logical NOT. Turns 0 (dollar words) into 1 and everything else into 0.
The IP wraps around to the beginning of the first line.
\ Reflect to NE. Switch to Ordinal.
o Implicitly convert the result to a string and print it.
Bounce off top boundary, move SE.
@ Terminate the program.