Tidak dapat dibaca , 1830 1796 1791 1771 1762 1745 1736 1727 1626 1606 1577 byte
Output dalam urutan abjad terbalik ( z
ke a
) tetapi sesuai dengan aturan Anda yang tampaknya diizinkan.
'"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""'"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""'"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "
Penjelasan
Pertama, untuk mendapatkan kesan tentang apa yang dapat dilakukan Unreadable, berikut ini adalah operasi dasarnya:
- Anda memiliki sel tak terbatas sel bilangan bulat ukuran tak terbatas
- Anda tidak memiliki penunjuk memori seperti di Brainfuck; alih-alih, Anda menentukan sel dengan lokasi mereka pada rekaman itu. Ini berarti Anda dapat "membaca nilai # 4" atau "membaca nilai # (nilai baca # 4)" (double-dereference).
- Anda hanya bisa membaca atau menulis sel-sel memori (tidak secara langsung kenaikan / penurunan seperti di Brainfuck).
- Anda bisa menambah / mengurangi nilai dalam ekspresi. Dengan demikian, untuk kenaikan sel memori Anda harus membaca , kenaikan , menulis , atau berbeda menempatkan:
write(x, inc(read(x)))
.
- Ada sementara loop dan kondisional ternary yang hanya dapat memeriksa nol vs non-nol.
Program ini menggunakan rekaman itu sebagai berikut. Nama-nama variabel akan digunakan dalam pseudocode nanti di bawah ini. Juga, ini mendokumentasikan versi pertama (yang 1830 byte); lihat pengeditan di bagian bawah untuk apa yang berubah sejak itu.
- Sel 0: variabel
q
- Sel 1: variabel
a
, p
,ch
- Sel 2: variabel
hash
,v
- Sel 3: variabel
b
,r
- Sel 4: variabel
aa
,l
- Sel 5: tetap 0 untuk menandai "akhir" dari string angka desimal
- Sel 6–95: menyimpan string angka desimal ke belakang
- Sel 96–121: menyimpan jumlah suara yang akan dikurangkan dari pengguna
a
(96) hingga z
(121) (kode ASCII surat itu dikurangi satu).
- Sel 4657–7380: ingat kombinasi pemilih / pemilih yang telah dijumpai berapa kali. Sel-sel ini hanya memiliki 4 nilai yang mungkin:
0
= belum terlihat, -1
= terlihat sekali, -2
= terlihat dua kali, -3
= terlihat beberapa kali lebih dari 2.
Algoritma pada dasarnya melanjutkan sebagai berikut:
- Terus membaca pasangan karakter
a
dan b
. Hitung nilai hash (a-2)*(a-1)+b-1
, yang unik untuk setiap kombinasi huruf a – z.
- Periksa sel memori pada nilai hash (
*hash
). Jika itu -3
, pengguna sudah memenuhi syarat untuk penghapusan suara, jadi tambahlah *(b-1)
. Kalau tidak, pengurangan *hash
. Jika itu sekarang -3
, pengguna baru saja menjadi layak untuk penghapusan suara setelah tiga kejadian, sehingga kenaikan *(b-1)
oleh 3
.
- Setelah ini, telusuri karakter dengan urutan terbalik (
z
ke a
) dan keluarkan karakter yang perlu dikurangi suara. Ini membutuhkan pembagian integer manual sebesar 10 untuk menerjemahkan angka menjadi angka desimal.
Dengan semua yang diklarifikasi, inilah yang tampak seperti program sebagai pseudocode:
// Read pairs of characters
while (a = read) + 1 {
b = read
// Calculate hash = (a-1)*(a-2)/2 + b-1
// This also sets a = b-1
hash = 0
while --a {
aa = a
while --aa {
++hash
}
}
while --b {
++a
++hash
}
// If this combination has just been seen for the third time,
// increment *a by 3; if more than third time, increment *a by 1
*a = (*hash + 3) ? ((--*hash) + 3 ? *a : (*a+3)) : (*a+1)
}
// Loop through the characters z to a
l = 27
while --l { // l loops from 26 to 1 (not 0)
(v = *(ch = l + 95)) ? { // 'a' is ASCII 97, but cell 96
print (ch+1) // print the votee
// Now we need to turn the number v into decimal.
// p points to where we are storing decimal digits.
p = 5
while v {
// Integer division by 10 (q=quotient, r=remainder)
r = (q = 0)
while v {
--v
(++r - 10) ? 1 : {
r = 0
++q
}
}
// Store digit ASCII character
*(++p) = r + 48 // 48 = '0'
v = q
}
// Now output all the digit ASCII characters in reverse order
while *p {
print *(--p + 1)
}
} : 1
}
Sunting 1, 1830 → 1796: Menyadari bahwa saya dapat menggunakan kembali nilai loop sementara di satu tempat.
Sunting 2, 1796 → 1791: Menghidupkan program sedikit lebih kecil jika, daripada menggunakan sel 6–95, saya menyimpan angka desimal dalam sel bernomor negatif (–1 dan seterusnya). Sebagai bonus tambahan, program ini tidak lagi terbatas pada 10⁹⁰ suara!
Sunting 3, 1791 → 1771: Alih-alih menetapkan hasil *(ch = l + 95)
untuk v
, sekarang saya menugaskan ke q
dan kemudian memindahkan tugas v = q
ke dalam kondisi sementara, mengambil kode ke 1777 byte. Kemudian tukar lokasi q
dan v
pada kaset karena q
sekarang 1 lebih umum daripada v
.
Sunting 4, 1771 → 1762: Duh. Menginisialisasi hash
ke 1 bukannya 0 adalah 9 byte lebih pendek. Kode hash sekarang 1 lagi, yang tidak masalah.
Sunting 5, 1762 → 1745: Jika saya menginisialisasi q
dan r
ke 1 alih-alih 0, saya harus memercikkan beberapa -1
di beberapa tempat untuk memperbaikinya, dan semuanya sepertinya dibatalkan - kecuali bahwa while v { --v; [...] }
loop sekarang perlu menjalankan satu iterasi yang lebih sedikit, yang bisa saya lakukan dengan mengatakan while --v { [...] }
, yaitu 26 karakter lebih pendek.
Sunting 6, 1745 → 1736: Alih-alih { r = 1; ++q }
, kita dapat menulis q = *((r = 1)+1)+1
. Ini bergantung pada fakta yang q
ada di slot variabel # 2. Jika ada di slot # 1 ini akan lebih pendek, tetapi keseluruhan program akan lebih lama secara keseluruhan.
Sunting 7, 1745 → 1727: Kembalikan Sunting 6 dan alih-alih mencapai penghematan dengan menggariskan bagian terdalam sementara loop ke dalam ekspresi yang menghitung kode ASCII digit, yang juga berakhir pada 1736 byte ... tetapi kemudian menyimpan instruksi penurunan (9 byte) ) dengan mengubah ((++r) - 11) ? r :
ke (r - 10) ? ++r :
.
Sunting 8, 1727 → 1626: Mengolah kembali perhitungan hash. Sekarang menggunakan satu loop sementara lebih sedikit. Lokasi sel sekarang pada kode ASCII mereka yang sebenarnya (tidak mati oleh 1 lagi). Variabel yang diacak ulang ke lokasi yang berbeda pada kaset karena sekarang terjadi dengan frekuensi yang berbeda.
Sunting 9, 1626 → 1606: Inlining lebih gila. Tubuh loop sementara pertama sekarang terlihat seperti ini:
// b = next char
*(b = (hash = read)) = {
// hash = b + (a-1)*(a-2)/2
while (a2 = --a) {
while --a2 {
++hash
}
}
// If this combination has just been seen for the third time,
// increment *b by 3; if more than third time, increment *b by 1
(*hash + 3) ? ((--*hash) + 3 ? *b : (*b+3)) : (*b+1)
}
dan tugas variabel sekarang hampir sepenuhnya berubah.
Mengedit 10, 1606 → 1577: Saya mengamati bahwa a
dan a2
keduanya dikurangi menjadi 0 sementara loop, jadi jika saya bisa memasangkan p
dengan salah satu dari mereka, tetapi tidak dengan ch
, saya tidak perlu menginisialisasi p
ke 0
(yang biaya 29 bytes). Ternyata saya bisa melakukannya dengan menukar p
dan r
. Variabel assigment terbaru (dan frekuensi kemunculannya dalam kode) sekarang adalah:
0 = v (3) (total 3)
1 = hash (6), r (5), ch (2) (total 13)
2 = b (4), q (5) (total 9)
3 = a (3), p (5) (total 8)
4 = a2 (3), l (4) (total 7)
nanananananananabatman
kasus uji.