Rubi
Rev 3, 55bytes
i=1
'S, OJ1*$HCH(#%0'.bytes{|e|puts "%x"%i+=e*130&9011}
Sebagai pengembangan lebih lanjut tentang ide Randomra, pertimbangkan output dan tabel perbedaan di bawah ini. Tabel perbedaan dapat dikompresi seperti sebelumnya, dan diperluas dengan mengalikan dengan 65 = binary 1000001 dan menerapkan topeng 11001100110011. Namun, Ruby tidak dapat diprediksi dengan karakter 8 bit (ia cenderung menafsirkannya sebagai Unicode.)
Anehnya, kolom terakhir seluruhnya sama. Karena itu, dalam kompresi kita dapat melakukan pengalihan hak pada data. Ini memastikan semua kode ASCII 7 bit. Dalam ekspansi, kita cukup mengalikan dengan 65 * 2 = 130 bukannya 65.
Kolom pertama juga seluruhnya genap. Karena itu kita dapat menambahkan 1 ke setiap elemen (32 ke setiap byte) jika perlu, untuk menghindari karakter kontrol. 1 yang tidak diinginkan dihapus dengan menggunakan mask 10001100110011 = 9011 sebagai gantinya 11001100110011.
Solution 59 of document linked in question
Start0001
Out Diff
2223 2222
2433 0210
2433 0000
4445 2012
6555 2110
6577 0022
6687 0110
6887 0200
8897 2010
aa99 2202
caa9 2010
cab9 0010
cbbb 0102
cdbd 0202
cddd 0020
Meskipun saya menggunakan 15 byte untuk tabel, saya hanya benar-benar menggunakan 6 bit setiap byte, yang merupakan total 90 bit. Sebenarnya hanya ada 36 nilai yang mungkin untuk setiap byte, yang merupakan 2.21E23 kemungkinan secara total. Itu akan cocok dengan 77 bit entropi.
Rev 2, 58 byte, menggunakan pendekatan incremental Randomra
i=0
'UPEIP@bPHPBETTEPRADT'.bytes{|e|puts "%x"%i+=e*65&819}
Akhirnya, sesuatu yang lebih pendek dari solusi naif. Pendekatan incremental Randomra, dengan metode bytepacking dari Rev 1.
Rev 1, 72 byte, versi golf rev 0
Beberapa perubahan dilakukan pada baseline untuk mengakomodasi penyusunan ulang kode karena alasan bermain golf, tetapi masih masuk lebih lama daripada solusi naif.
i=0
'UPUIYD&!)$&V*).);c+*'.bytes{|e|i+=1;puts "%x"%(i/2*273+(e*65&819))}
Offset dikodekan ke dalam masing-masing karakter string sihir dalam basis 4 dalam format BAC
, yaitu dengan 1 yang mewakili simbol tangan kanan, 16 yang mewakili simbol tengah, dan simbol kiri diseret ke posisi 4 itu. Untuk mengekstraknya, kode ascii dikalikan dengan 65 (biner 1000001) untuk diberikanBACBAC
, kemudian di-anded dengan 819 (binary 1100110011) untuk diberikan.A.B.C
.
Beberapa kode ascii memiliki set bit ke-7, yaitu mereka 64 lebih tinggi dari nilai yang diperlukan, untuk menghindari karakter kontrol. Karena bit ini dihapus oleh mask 819, ini tidak penting, kecuali ketika nilai C
3, yang menyebabkan akumulasi. Ini harus diperbaiki di satu tempat saja (bukannya g
kita harus menggunakanc
.)
Rev 0, versi tidak dikoleksi
a= %w{000 010 000 201 100 100 011 021 110 120 011 112 111 221 211 221 122 123 112 222}
i=2
a.each{|e|puts "%x"%(i/2*273+e.to_i(16));i+=1}
Keluaran
111
121
222
423
433
433
455
465
665
675
677
778
888
998
a99
aa9
abb
abc
bbc
ccc
Penjelasan
Dari solusi berikut, saya kurangi baseline, memberikan offset yang saya simpan sebagai data. Baseline diregenerasi sebagai angka heksadesimal dalam kode dengan i/2*273
(273 desimal = 111 hex.)
solution baseline offset
AAA AAA 000
ABA AAA 010
BBB BBB 000
DBC BBB 201
DCC CCC 100
DCC CCC 100
DEE DDD 011
DFE DDD 021
FFE EEE 110
FGE EEE 120
FGG FFF 011
GGH FFF 112
HHH GGG 111
IIH GGG 221
JII HHH 211
JJI HHH 221
JKK III 122
JKL III 123
KKL JJJ 112
LLL JJJ 222