Tidak buruk untuk Turing turing ...
N
Count i while _%128-9 {
Count x while _/128%2 {
Write 40
_+128
}
Write _%128
_+128-_%128+N
}
Count j while _/256-j {
Write 41
}
(Ya, semua spasi putih itu wajib.)
Catatan: karena keterbatasan input Acc !! , tidak mungkin untuk membaca serangkaian karakter acak tanpa pembatas akhir. Oleh karena itu, program ini mengharapkan input (pada stdin) sebagai string yang diikuti oleh karakter tab.
Acc !! ?
Ini adalah bahasa yang saya buat yang sepertinya tidak bisa digunakan . Satu-satunya tipe data adalah bilangan bulat, satu-satunya konstruksi aliran kontrol adalah Count x while y
loop, dan satu-satunya cara untuk menyimpan data adalah akumulator tunggal _
. Input dan output dilakukan satu karakter pada satu waktu, menggunakan nilai khusus N
dan Write
pernyataan. Terlepas dari keterbatasan ini, saya cukup yakin bahwa Acc !! adalah Turing-complete.
Penjelasan
Strategi dasar dalam Acc !! pemrograman adalah dengan menggunakan mod %
dan integer division /
untuk secara konseptual mempartisi akumulator, memungkinkannya untuk menyimpan beberapa nilai sekaligus. Dalam program ini, kami menggunakan tiga bagian seperti itu: tujuh bit urutan terendah ( _%128
) menyimpan kode ASCII dari input; bit berikutnya ( _/128%2
) menyimpan nilai flag; dan bit yang tersisa ( _/256
) menghitung jumlah parens dekat yang akan kita butuhkan.
Masukkan Acc !! berasal dari nilai khusus N
, yang membaca satu karakter dan mengevaluasi kode ASCII-nya. Pernyataan apa pun yang hanya terdiri dari ekspresi memberikan hasil ekspresi itu ke akumulator. Jadi kita mulai dengan menyimpan kode karakter pertama di akumulator.
_%128
akan menyimpan karakter yang terakhir dibaca. Jadi loop pertama berjalan sementara _%128-9
adalah bukan nol - yaitu, sampai karakter saat ini adalah tab.
Di dalam loop, kami ingin mencetak (
kecuali kami berada di iterasi pertama. Sejak Acc !! tidak memiliki pernyataan if, kita harus menggunakan loop untuk conditional. Kami menggunakan bit 128 dari akumulator _/128%2
,, sebagai nilai bendera. Pada pass pertama, satu-satunya hal dalam akumulator adalah nilai ASCII <128, jadi flagnya adalah 0 dan loop dilewati. Pada setiap operan berikutnya, kami akan memastikan bahwa benderanya 1.
Di dalam Count x
loop (setiap kali flag adalah 1), kami menulis paren terbuka (ASCII 40
) dan menambahkan 128 ke akumulator, dengan demikian mengatur flag ke 0 dan keluar dari loop. Ini juga terjadi untuk meningkatkan nilai _/256
, yang akan kita gunakan sebagai penghitungan dari orang tua kita untuk menjadi output.
Terlepas dari nilai flag, kami menulis char input terbaru, yang sederhana _%128
.
Tugas berikutnya ( _+128-_%128+N
) melakukan dua hal. Pertama, dengan menambahkan 128, itu menetapkan bendera untuk waktu berikutnya melalui loop. Kedua, itu nol _%128
slot, membaca karakter lain, dan menyimpannya di sana. Lalu kita mengulang.
Ketika Count i
loop keluar, kami baru saja membaca karakter tab, dan nilai akumulator terurai seperti ini:
_%128
: 9
(karakter tab)
_/128%2
: 1
(bendera)
_/256
: jumlah karakter yang dibaca, minus 1
(Yang minus 1 adalah karena kita hanya menambahkan 128 ke akumulator sekali selama melewati pertama melalui loop utama.) Yang kita butuhkan sekarang adalah parens-dekat. Count j while _/256-j
loop _/256
kali, menulis close-paren (ASCII 41
) setiap kali. Voila!