Berikut adalah file teks ASCII 1.2Mb yang berisi teks Moby-Dick Herman Melville ; atau, Paus . Tugas Anda adalah menulis program atau fungsi (atau kelas, dll. - lihat di bawah) yang akan diberikan file ini satu karakter pada satu waktu, dan pada setiap langkah harus menebak karakter berikutnya.
Ini adalah tantangan kode . Skor Anda akan
2*L + E
di mana L
ukuran pengiriman Anda dalam byte, dan E
jumlah karakter yang ditebaknya salah. Skor terendah menang.
Keterangan lebih lanjut
Kiriman Anda akan berupa program atau fungsi (dll.) Yang akan dipanggil atau dipanggil atau dikirim data beberapa kali. (1215235 kali tepatnya.) Ketika itu disebut untuk n th waktu itu akan diberi n th karakter whale.txt
atau whale2.txt
dan harus keluaran menebak-nya untuk ( n + 1 ) th karakter. The E
komponen skor yang akan menjadi jumlah karakter yang menebak benar.
Sebagian besar pengiriman harus menyimpan beberapa keadaan di antara doa, sehingga mereka dapat melacak berapa kali mereka dipanggil dan apa input sebelumnya. Anda dapat melakukan ini dengan menulis ke file eksternal, dengan menggunakan static
atau variabel global, dengan mengirimkan kelas daripada fungsi, menggunakan negara monad, atau apa pun yang berfungsi untuk bahasa Anda. Kiriman Anda harus menyertakan kode apa pun yang diperlukan untuk menginisialisasi keadaannya sebelum permohonan pertama.
Program Anda harus berjalan secara deterministik, sehingga selalu membuat tebakan yang sama dengan input yang sama (dan karenanya selalu mendapat skor yang sama).
Jawaban Anda harus mencakup tidak hanya kiriman Anda, tetapi juga kode yang Anda gunakan untuk menghitung E
bagian dari skornya. Ini tidak perlu ditulis dalam bahasa yang sama dengan kiriman Anda, dan tidak akan dihitung terhadap jumlah byte-nya. Anda didorong untuk membuatnya mudah dibaca.
Mengenai antarmuka antara kiriman Anda dan program penghitungan skor ini, semuanya baik-baik saja, asalkan program Anda selalu memberikan satu byte output sebelum menerima byte input berikutnya. (Jadi, misalnya, Anda tidak bisa hanya meneruskannya sebuah string yang berisi semua input dan mendapatkan kembali string yang berisi semua output.)
Anda benar-benar harus menjalankan program pengujian dan menghitung / memverifikasi skor Anda sebelum mengirimkan entri Anda. Jika kiriman Anda berjalan terlalu lambat untuk Anda memverifikasi skornya maka tidak memenuhi syarat untuk bersaing, bahkan jika Anda tahu berapa skornya pada prinsipnya.
The L
komponen skor Anda akan dihitung sesuai dengan aturan biasa untuk tantangan kode golf. Jika kiriman Anda akan berisi banyak file, harap perhatikan aturan penilaian dan struktur direktori dalam kasus itu. Data apa pun yang digunakan kode Anda harus dimasukkan dalam L
skor Anda .
Anda dapat mengimpor perpustakaan yang ada tetapi tidak dapat memuat file eksternal lainnya, dan kode Anda mungkin tidak mengakses whale.txt
atauwhale2.txt
file dengan cara apa pun selain yang dijelaskan di atas. Anda tidak boleh memuat jaringan saraf pra-terlatih atau sumber data statistik lainnya. (Tidak apa-apa menggunakan jaringan saraf, tetapi Anda harus memasukkan data bobot dalam kiriman Anda dan menghitungnya terhadap jumlah byte Anda.) Jika karena alasan tertentu bahasa atau perpustakaan Anda menyertakan fitur yang menyediakan beberapa atau semua teks Moby Dick , Anda tidak boleh menggunakan fitur itu. Selain itu, Anda dapat menggunakan fitur perpustakaan atau built-in apa saja yang Anda suka, termasuk yang berkaitan dengan pemrosesan teks, prediksi atau kompresi, asalkan itu bagian dari bahasa Anda atau perpustakaan standarnya. Untuk rutinitas khusus yang lebih eksotis dan khusus yang menyertakan sumber data statistik, Anda harus menerapkannya sendiri dan memasukkannya dalam jumlah byte Anda.
Kemungkinan beberapa pengiriman akan mencakup komponen yang dihasilkan sendiri oleh kode. Jika demikian, harap sertakan dalam jawaban Anda kode yang digunakan untuk membuatnya, dan jelaskan cara kerjanya . (Selama kode ini tidak diperlukan untuk menjalankan kiriman Anda, kode itu tidak akan dimasukkan dalam jumlah byte Anda.)
Untuk alasan historis, ada dua versi file, dan Anda dapat menggunakan salah satu dari mereka dalam sebuah jawaban. Dalam whale2.txt
(ditautkan di atas) teks tidak dibungkus, sehingga baris baru hanya muncul di akhir paragraf. Dalam whale.txt
teks asli , teks dibungkus dengan lebar 74 karakter, jadi Anda harus memprediksi akhir setiap baris serta memprediksi teks. Hal ini membuat tantangan lebih fiddly, jadi whale2.txt
direkomendasikan untuk jawaban baru. Kedua file berukuran sama, 1215236 byte.
Untuk meringkas, semua jawaban harus mencakup hal-hal berikut:
- Kiriman Anda sendiri. (Kode, plus file data apa pun yang digunakan - ini bisa berupa tautan jika besar.)
- Penjelasan tentang cara kerja kode Anda. Tolong jelaskan metode I / O serta bagaimana ia memprediksi karakter berikutnya. Penjelasan tentang algoritma Anda adalah penting, dan penjelasan yang baik akan menghasilkan hadiah dari saya.
- Kode yang Anda gunakan untuk mengevaluasi skor Anda. (Jika ini identik dengan jawaban sebelumnya, Anda dapat menautkannya.)
- Kode apa pun yang Anda gunakan untuk menghasilkan kiriman Anda, bersama dengan penjelasan kode itu. Ini termasuk kode yang Anda gunakan untuk mengoptimalkan parameter, menghasilkan file data dll. (Ini tidak dihitung terhadap jumlah byte Anda tetapi harus dimasukkan dalam jawaban Anda.)
Papan peringkat
Bounties
Dari waktu ke waktu saya akan menawarkan hadiah untuk mendorong pendekatan yang berbeda.
Yang pertama, 50 poin, diberikan kepada A. Rex untuk jawaban skor terbaik saat itu.
Yang kedua, 100 poin, juga diberikan kepada A. Rex, untuk jawaban yang sama, karena mereka menambahkan penjelasan yang sangat bagus untuk jawaban yang ada.
Hadiah berikutnya, 200 poin , akan diberikan kepada keduanya
- Jawaban kompetitif yang menggunakan teknik baru. (Ini akan didasarkan pada penilaian subyektif saya karena perwakilan saya yang masuk ke dalam karunia, tetapi Anda dapat mempercayai saya untuk bersikap adil. Perhatikan bahwa jawaban Anda perlu berisi penjelasan yang cukup bagi saya untuk memahami cara kerjanya!) Jawaban seperti itu perlu dapat mengambil skor teratas, itu hanya perlu dilakukan dengan cukup baik dibandingkan dengan jawaban yang ada. Saya sangat tertarik untuk melihat solusi berdasarkan jaringan saraf berulang, tapi saya akan menghadiahkan hadiah untuk apa pun yang tampaknya cukup berbeda dari model Markov yang mendominasi skor teratas saat ini.
Atau:
- Siapa pun yang mengalahkan skor tertinggi A. Rex (saat ini 444444), menggunakan metode apa pun.
Setelah nilai 200 poin diklaim saya kemungkinan besar akan menawarkan 400 poin satu, memperbarui persyaratan yang sesuai.
sumber
Jawaban:
/// , 2 * 1 + 1020874 = 1020876
Mencetak spasi.
sumber
Node.js, 2 * 224 + 524279 = 524727
Silakan merujuk ke log perubahan di akhir posting ini untuk pembaruan skor.
Fungsi mengambil dan mengembalikan byte.
Ini terdiri dari model PPM sederhana yang melihat 8 karakter terakhir untuk memprediksi yang berikutnya.
Kami memercayai pola panjang L ketika kami menjumpainya setidaknya T [L] kali, di mana T adalah array ambang arbitrer: [1,1,2,1,2,3,5,2] . Selain itu, kami selalu mempercayai pola yang cocok dengan karakter pertamanya
[A-Z '"(]
.Kami memilih pola tepercaya terpanjang dan mengembalikan prediksi dengan skor tertinggi yang terkait dengan pola ini pada saat panggilan.
Catatan
Ini jelas tidak dioptimalkan untuk kecepatan, tetapi beroperasi dalam waktu sekitar 15 detik di laptop saya.
Jika kami diizinkan untuk mengulangi proses beberapa kali berturut-turut tanpa mengatur ulang model, jumlah kesalahan akan konvergen ke ~ 268000 setelah 5 iterasi.
Tingkat keberhasilan fungsi prediksi saat ini adalah ~ 56,8%. Seperti yang diperhatikan oleh @immibis dalam komentar, jika tebakan yang salah dan benar tercampur menjadi satu, hasilnya bahkan tidak bisa dibaca.
Misalnya, cuplikan ini di dekat akhir buku:
menjadi:
Dengan mengganti tebakan buruk dengan garis bawah, kami memiliki gagasan yang lebih baik tentang fungsi yang benar:
NB : Contoh di atas dibuat dengan versi kode sebelumnya, bekerja pada versi pertama dari file input.
Kode uji
Ubah log
sumber
sidg tlanses,oeth to, shuld hottut tild aoersors Ch, th! Sa, yr! Sheu arinning whales aut ihe e sl he traaty of rrsf tg homn Bho dla tiasot a shab sor ty, af etoors tnd hocket sh bts ait mtubb tiddin tis aeewnrs, dnhost maundy cnd sner aiwt d boelh cheugh -aaieiyns aasiyns taaeiins! th, tla
. Terkadang berhasil mendapatkan beberapa kata lengkap. Sepertiwhales
.Perl, 2 · 70525 + 326508 = 467558
Prediktor
Untuk menjalankan program ini, Anda perlu file ini di sini , yang harus dinamai
B
. (Anda dapat mengubah nama file ini pada karakter karakter kedua diB
atas.) Lihat di bawah untuk cara membuat file ini.Program ini menggunakan kombinasi model Markov pada dasarnya seperti dalam jawaban ini oleh user2699 , tetapi dengan beberapa modifikasi kecil. Ini menghasilkan distribusi untuk karakter selanjutnya. Kami menggunakan teori informasi untuk memutuskan apakah akan menerima kesalahan atau menghabiskan sedikit penyimpanan dalam
B
petunjuk penyandian (dan jika demikian, bagaimana). Kami menggunakan kode aritmatika untuk menyimpan bit fraksional secara optimal dari model.Program ini panjangnya 582 byte (termasuk baris akhir yang tidak perlu) dan panjang file biner
B
adalah 6.9942 byte, jadi berdasarkan aturan untuk mencetak banyak file , kami mendapat skorL
582 + 69942 + 1 = 70525.Program ini hampir pasti membutuhkan arsitektur 64-bit (little-endian?). Diperlukan waktu sekitar 2,5 menit untuk menjalankan
m5.large
instance di Amazon EC2.Kode uji
Test harness menganggap pengajuan ada dalam file
submission.pl
, tetapi ini dapat dengan mudah diubah di baris kedua.Perbandingan teks
Sampel ini (dipilih dalam jawaban lain ) muncul agak terlambat dalam teks, sehingga model ini cukup berkembang pada titik ini. Ingat bahwa model ini ditambah oleh 70 kilobyte "petunjuk" yang secara langsung membantunya menebak karakter; itu tidak didorong hanya oleh potongan pendek kode di atas.
Menghasilkan petunjuk
Program berikut menerima kode pengiriman yang tepat di atas (pada input standar) dan menghasilkan
B
file yang tepat di atas (pada output standar):Diperlukan waktu kira-kira untuk berjalan seperti pengiriman, karena melakukan perhitungan yang sama.
Penjelasan
Di bagian ini, kami akan mencoba menjelaskan apa yang dilakukan solusi ini dengan cukup detail sehingga Anda dapat "mencobanya di rumah" sendiri. Teknik utama yang membedakan jawaban ini dari yang lain adalah beberapa bagian di bawah sebagai mekanisme "mundur", tetapi sebelum kita sampai di sana, kita perlu mengatur dasar-dasarnya.
Model
Bahan dasar dari solusi adalah model bahasa. Untuk tujuan kami, model adalah sesuatu yang mengambil sejumlah teks bahasa Inggris dan mengembalikan distribusi probabilitas pada karakter berikutnya. Ketika kami menggunakan model, teks bahasa Inggris akan menjadi beberapa awalan (benar) dari Moby Dick. Harap dicatat bahwa output yang diinginkan adalah distribusi , dan bukan hanya tebakan tunggal untuk karakter yang paling mungkin.
Dalam kasus kami, kami pada dasarnya menggunakan model dalam jawaban ini oleh user2699 . Kami tidak menggunakan model dari jawaban dengan skor tertinggi (selain dari milik kami) oleh Anders Kaseorg justru karena kami tidak dapat mengekstraksi distribusi daripada hanya satu tebakan terbaik. Secara teori, jawaban itu menghitung rata-rata geometris tertimbang, tetapi kami mendapat hasil yang sedikit buruk ketika kami menafsirkannya secara harfiah. Kami "mencuri" model dari jawaban lain karena "saus rahasia" kami bukanlah model melainkan pendekatan keseluruhan. Jika seseorang memiliki model "lebih baik", maka mereka harus bisa mendapatkan hasil yang lebih baik menggunakan sisa teknik kami.
Sebagai komentar, sebagian besar metode kompresi seperti Lempel-Ziv dapat dilihat sebagai "model bahasa" dengan cara ini, meskipun orang mungkin harus sedikit menyipit. (Ini sangat sulit untuk sesuatu yang melakukan transformasi Burrows-Wheeler!) Juga, perhatikan bahwa model oleh user2699 adalah modifikasi dari model Markov; intinya tidak ada lagi yang kompetitif untuk tantangan ini atau bahkan pemodelan teks secara umum.
Arsitektur keseluruhan
Untuk keperluan pemahaman, senang memecah arsitektur keseluruhan menjadi beberapa bagian. Dari perspektif tingkat tertinggi, perlu ada sedikit kode manajemen negara. Ini tidak terlalu menarik, tetapi untuk kelengkapan kami ingin menekankan bahwa pada setiap titik program diminta untuk tebakan berikutnya, itu telah tersedia untuknya awalan yang benar dari Moby Dick. Kami tidak menggunakan tebakan salah kami di masa lalu dengan cara apa pun. Demi efisiensi, model bahasa mungkin dapat menggunakan kembali statusnya dari karakter N pertama untuk menghitung statusnya untuk karakter pertama (N + 1), tetapi pada prinsipnya, ia dapat menghitung ulang hal-hal dari awal setiap kali dipanggil.
Mari kita kesampingkan "driver" dasar program ini dan mengintip bagian dalam yang menebak karakter selanjutnya. Ini membantu secara konseptual untuk memisahkan tiga bagian: model bahasa (dibahas di atas), file "petunjuk", dan "penerjemah". Pada setiap langkah, penerjemah akan meminta model bahasa untuk distribusi untuk karakter berikutnya dan mungkin membaca beberapa informasi dari file petunjuk. Maka akan menggabungkan bagian-bagian ini menjadi tebakan. Tepatnya informasi apa yang ada dalam file petunjuk serta bagaimana penggunaannya akan dijelaskan nanti, tetapi untuk saat ini membantu memisahkan bagian-bagian ini secara mental. Perhatikan bahwa implementasi-bijaksana, file petunjuk secara harfiah file terpisah (biner) tetapi bisa berupa string atau sesuatu yang disimpan di dalam program. Sebagai perkiraan,
Jika seseorang menggunakan metode kompresi standar seperti bzip2 seperti dalam jawaban ini , file "hints" sesuai dengan file yang dikompresi. "Interpreter" sesuai dengan decompressor, sedangkan "model bahasa" agak implisit (seperti yang disebutkan di atas).
Mengapa menggunakan file petunjuk?
Mari kita ambil contoh sederhana untuk dianalisis lebih lanjut. Misalkan teks
N
panjang karakter dan didekati dengan baik oleh model di mana setiap karakter (independen) hurufE
dengan probabilitas sedikit kurang dari setengah,T
sama dengan probabilitas sedikit kurang dari setengah, danA
dengan probabilitas 1/1000 = 0,1%. Mari kita asumsikan tidak ada karakter lain yang mungkin; dalam kasus apa pun,A
ini cukup mirip dengan kasus karakter yang sebelumnya tidak terlihat tiba-tiba.Jika kita beroperasi dalam rezim L 0 (seperti kebanyakan, tetapi tidak semua, dari jawaban lain untuk pertanyaan ini), tidak ada strategi yang lebih baik untuk penerjemah daripada memilih salah satu dari
E
danT
. Rata-rata, itu akan mendapatkan sekitar setengah dari karakter yang benar. Jadi E ≈ N / 2 dan skor ≈ N / 2 juga. Namun, jika kita menggunakan strategi kompresi, maka kita dapat memampatkan sedikit lebih dari satu bit per karakter. Karena L dihitung dalam byte, kita mendapatkan L ≈ N / 8 dan dengan demikian skor ≈ N / 4, dua kali lebih baik dari strategi sebelumnya.Mencapai tingkat ini sedikit lebih dari satu bit per karakter untuk model ini sedikit nontrivial, tetapi satu metode adalah pengkodean aritmatika.
Pengkodean aritmatika
Seperti yang umum diketahui, pengkodean adalah cara mewakili beberapa data menggunakan bit / byte. Sebagai contoh, ASCII adalah pengkodean 7 bit / karakter teks bahasa Inggris dan karakter terkait, dan itu adalah pengkodean file Moby Dick asli yang sedang dipertimbangkan. Jika beberapa huruf lebih umum daripada yang lain, maka penyandian lebar-tetap seperti ASCII tidak optimal. Dalam situasi seperti itu, banyak orang meraih kode Huffman . Ini optimal jika Anda menginginkan kode tetap (bebas awalan) dengan jumlah bit integer per karakter.
Namun, pengkodean aritmatika bahkan lebih baik. Secara kasar, ia dapat menggunakan bit "fraksional" untuk menyandikan informasi. Ada banyak panduan untuk coding aritmatika yang tersedia online. Kami akan melewatkan detailnya di sini (terutama dari implementasi praktis, yang bisa sedikit rumit dari perspektif pemrograman) karena sumber daya lain yang tersedia secara online, tetapi jika seseorang mengeluh, mungkin bagian ini dapat diperlihatkan lebih lanjut.
Jika seseorang memiliki teks yang sebenarnya dihasilkan oleh model bahasa yang dikenal, maka pengkodean aritmatika memberikan pengkodean teks yang pada dasarnya optimal dari model itu. Dalam beberapa hal, ini "memecahkan" masalah kompresi untuk model itu. (Dengan demikian dalam praktiknya, masalah utama adalah bahwa model tidak diketahui, dan beberapa model lebih baik daripada yang lain dalam pemodelan teks manusia.) Jika tidak diizinkan untuk membuat kesalahan dalam kontes ini, maka dalam bahasa bagian sebelumnya , salah satu cara untuk menghasilkan solusi untuk tantangan ini adalah dengan menggunakan encoder aritmatika untuk menghasilkan file "petunjuk" dari model bahasa dan kemudian menggunakan dekoder aritmatika sebagai "penerjemah".
Dalam pengkodean yang pada dasarnya-optimal ini, kita akhirnya menghabiskan -log_2 (p) bit untuk karakter dengan probabilitas p, dan laju bit keseluruhan dari pengkodean adalah entropi Shannon . Ini berarti bahwa karakter dengan probabilitas dekat 1/2 membutuhkan waktu sekitar satu bit untuk mengkodekan, sedangkan karakter dengan probabilitas 1/1000 membutuhkan sekitar 10 bit (karena 2 ^ 10 kira-kira 1000).
Tetapi metrik penilaian untuk tantangan ini dipilih dengan baik untuk menghindari kompresi sebagai strategi optimal. Kita harus mencari cara untuk membuat beberapa kesalahan sebagai tradeoff untuk mendapatkan file petunjuk yang lebih pendek. Sebagai contoh, salah satu strategi yang mungkin dicoba adalah strategi percabangan sederhana: kami biasanya mencoba menggunakan pengkodean aritmatika ketika kami bisa, tetapi jika distribusi probabilitas dari model itu "buruk" dalam beberapa cara kami hanya menebak karakter yang paling mungkin dan tidak t coba menyandikannya.
Mengapa melakukan kesalahan?
Mari kita menganalisis contoh dari sebelumnya untuk memotivasi mengapa kita mungkin ingin membuat kesalahan "dengan sengaja". Jika kita menggunakan pengkodean aritmatika untuk menyandikan karakter yang benar, kita akan menghabiskan kira-kira satu bit dalam kasus
E
atauT
, tetapi sekitar sepuluh bit dalam kasus suatuA
.Secara keseluruhan, ini adalah pengkodean yang cukup bagus, menghabiskan sedikit lebih sedikit per karakter meskipun ada tiga kemungkinan; pada dasarnya,
A
ini sangat tidak mungkin dan kami tidak menghabiskan sepuluh bit yang sesuai terlalu sering. Namun, bukankah lebih baik jika kita bisa membuat kesalahan sebagai gantinyaA
? Bagaimanapun, metrik untuk masalah ini menganggap 1 byte = 8 bit panjangnya setara dengan 2 kesalahan; jadi sepertinya orang harus lebih memilih kesalahan daripada menghabiskan lebih dari 8/2 = 4 bit pada sebuah karakter. Menghabiskan lebih dari satu byte untuk menyimpan satu kesalahan pasti terdengar kurang optimal!Mekanisme "mundur"
Bagian ini menjelaskan aspek pintar utama dari solusi ini, yang merupakan cara untuk menangani tebakan yang salah tanpa biaya panjang.
Untuk contoh sederhana yang telah kami analisis, mekanisme mundur sangat mudah. Juru bahasa membaca sedikit dari file petunjuk. Jika 0, itu menebak
E
. Jika itu adalah 1, ia menebakT
. Kali berikutnya dipanggil, ia melihat apa karakter yang benar. Jika file petunjuk diatur dengan baik, kami dapat memastikan bahwa dalam kasus seorangE
atauT
, penerjemah menebak dengan benar. Tapi bagaimana dengan ituA
? Gagasan mekanisme mundur adalah tidak kodeA
sama sekali . Lebih tepatnya, jika penerjemah kemudian mengetahui bahwa karakter yang benar adalahA
, maka secara metaforis " memutar ulang kaset": ia mengembalikan bit yang dibacanya sebelumnya. Bit yang dibaca memang bermaksud untuk kodeE
atauT
, tapi tidak sekarang; itu akan digunakan nanti. Dalam contoh sederhana ini, ini pada dasarnya berarti bahwa ia terus menebak karakter yang sama (E
atauT
) sampai benar; kemudian membaca sedikit lagi dan terus berjalan.Pengkodean untuk file petunjuk ini sangat sederhana: ubah semua
E
s menjadi 0 bit danT
s menjadi 1 bit, semuanya mengabaikanA
sepenuhnya s. Dengan analisis di akhir bagian sebelumnya, skema ini membuat beberapa kesalahan tetapi mengurangi skor secara keseluruhan dengan tidak menyandikan salah satu dariA
s. Sebagai efek yang lebih kecil, itu sebenarnya menghemat panjang file petunjuk juga, karena kita akhirnya menggunakan tepat satu bit untuk masing-masingE
danT
, alih-alih sedikit lebih dari sedikit.Teorema kecil
Bagaimana kita memutuskan kapan harus membuat kesalahan? Misalkan model kita memberi kita distribusi probabilitas P untuk karakter berikutnya. Kami akan memisahkan karakter yang mungkin menjadi dua kelas: kode dan bukan kode . Jika karakter yang benar tidak dikodekan, maka kita akan berakhir menggunakan mekanisme "mundur" untuk menerima kesalahan tanpa biaya panjang. Jika karakter yang benar dikodekan, maka kita akan menggunakan beberapa distribusi Q lainnya untuk menyandikannya menggunakan pengkodean aritmatika.
Tetapi distribusi Q apa yang harus kita pilih? Tidak terlalu sulit untuk melihat bahwa karakter yang dikode semuanya harus memiliki probabilitas yang lebih tinggi (dalam P) daripada karakter yang tidak diberi kode. Juga, distribusi Q seharusnya hanya menyertakan karakter kode; lagipula, kita tidak mengkode yang lain, jadi kita seharusnya tidak "menghabiskan" entropi untuk mereka. Agak sulit untuk melihat bahwa distribusi probabilitas Q harus proporsional dengan P pada karakter kode. Menyatukan pengamatan ini berarti bahwa kita harus mengkode karakter yang paling mungkin tetapi mungkin bukan karakter yang kurang mungkin, dan bahwa Q hanya P yang ditulis ulang pada karakter yang dikode.
Lebih jauh lagi ternyata ada teorema keren tentang "cutoff" mana yang harus dipilih untuk karakter pengkodean: Anda harus mengkode karakter selama paling tidak 1/5, 393 lebih besar dari kemungkinan kombinasi karakter berkode lainnya. Ini "menjelaskan" penampilan konstanta yang tampaknya acak
5.393
mendekati akhir program di atas. Angka 1 / 5.393 ≈ 0,18542 adalah solusi untuk persamaan -p log (16) - p log p + (1 + p) log (1 + p) = 0 .Mungkin ide yang masuk akal untuk menuliskan prosedur ini dalam kode. Cuplikan ini ada di C ++:
Menyatukan semuanya
Bagian sebelumnya sayangnya sedikit teknis, tetapi jika kita menyatukan semua bagian lainnya, strukturnya adalah sebagai berikut. Setiap kali program diminta untuk memprediksi karakter berikutnya setelah karakter yang diberikan benar:
Pengkodean file petunjuk beroperasi dengan cara yang sama. Dalam hal ini, program tahu apa karakter selanjutnya yang benar. Jika itu adalah karakter yang harus dikodekan, maka tentu saja orang harus menggunakan encoder aritmatika di atasnya; tetapi jika itu bukan karakter kode, itu hanya tidak memperbarui keadaan aritmatika encoder.
Jika Anda memahami latar belakang teori-informasi seperti distribusi probabilitas, entropi, kompresi, dan pengkodean aritmatika tetapi mencoba dan gagal memahami posting ini (kecuali mengapa teorema itu benar), beri tahu kami dan kami dapat mencoba untuk menyelesaikannya. Terima kasih sudah membaca!
sumber
B
file? Jika demikian, dapatkah Anda memasukkannya dalam jawaban Anda?Python 3, 2 · 267 + 510193 = 510727
Prediktor
Ini menggunakan kombinasi Bayesian tertimbang dari urutan 0,…, 16 model Markov, dengan bobot [1, 6, 12, 30, 65, 99, 87, 117, 118, 89, 95, 118, 96, 184, 126, 219, 126].
Hasilnya tidak terlalu peka terhadap pemilihan bobot ini, tetapi saya mengoptimalkannya karena saya bisa, menggunakan algoritme pendakian bukit penerimaan terlambat yang sama yang saya gunakan dalam jawaban saya untuk "Menyatukan mayoritas Senat" , di mana setiap kandidat mutasi adalah hanya kenaikan ± 1 untuk satu berat.
Kode uji
sumber
b"\0\3\6\r\34'&-20'\22!P\n[\26"
adalah representasi bobot ascii, di mana nilai-nilai kecil yang tidak dapat dicetak lolos dalam oktal.Python 3 ,
2 * 279 + 592920 = 5934782 * 250 + 592467 = 5929672 * 271 + 592084 = 5926262 * 278 + 592059 = 5926152 * 285 + 586660 = 5872302 * 320 + 585161 = 5858012 * 339 + 585050 = 585728Cobalah online!
Fungsi menggunakan variabel global. Belajar sambil jalan, membangun model di tingkat kata: mengingat apa yang terlihat sejauh ini dalam kata ini , apa karakter berikutnya yang paling umum? Semakin banyak input yang masuk, ia belajar kata-kata umum dari teks dengan cukup baik, dan juga mempelajari karakter yang paling umum untuk memulai kata berikutnya .
Sebagai contoh:
Pada awalnya tidak terlalu baik, tetapi pada akhirnya ada sebagian besar kata-kata yang sebenarnya keluar. Opsi mundur adalah spasi, dan setelah satu spasi itu adalah "a", kecuali huruf sebelumnya adalah salah satu dari "nedtfo", digit, atau tanda hubung atau tanda kutip. Itu juga secara agresif memprediksi jeda baris setelah 71 karakter, atau jika spasi diharapkan setelah 66. Keduanya hanya disetel ke data ("t" jauh lebih umum setelah spasi, tetapi lebih sering sudah diprediksi, jadi " a "adalah tebakan yang lebih baik di luar enam kasus khusus).
Mempelajari pasangan kata apa yang berjalan bersama dan melakukan preseeding pemetaan ternyata tidak bermanfaat.
Itu berakhir dengan teks seperti ini:
yang sesuai dengan bagian input ini:
Anda dapat melihat di mana kata benda yang tepat keluar dengan cukup baik, tetapi ujung-ujung kata sebagian besar benar juga. Ketika itu terlihat "dou" itu mengharapkan "keraguan", tetapi begitu "l" muncul itu mendapat "doubloon".
Jika Anda menjalankannya untuk kedua kalinya dengan model yang sama dengan yang baru dibangun, ia akan segera mendapatkan 92k yang benar (51,7% -> 59,3%), tetapi selalu di bawah 60% sejak iterasi kedua aktif.
Kode pengukuran ada di tautan TIO, atau ini versi yang sedikit lebih baik:
guess.txt
memiliki hasil tebakan pada akhirnya.sumber
C ++, skor: 2 * 132 + 865821 = 866085
Terima kasih kepada @ Quentin karena telah menghemat 217 byte!
Solusi yang sangat sederhana yang, diberikan karakter, hanya menampilkan karakter yang paling sering muncul setelah karakter input.
Verifikasi skor dengan:
Sunting: Menggunakan
whale2.txt
memberi skor yang lebih baik.sumber
L
untuk menyimpan banyak karakter :)Python, 2 * 516 + 521122 = 522154
Algoritma:
Namun pengajuan python lain, algoritma ini menghitung huruf berikutnya yang paling mungkin melihat urutan panjang 1, ..., l. Jumlah probabilitas digunakan, dan ada beberapa trik untuk mendapatkan hasil yang lebih baik.
Hasil:
Sebagian besar omong kosong, meskipun Anda dapat melihatnya mengambil frasa sesekali, seperti "Father Mapple".
Kode uji:
Cukup sederhana, menampilkan beberapa contoh teks pada titik yang berbeda. Gunakan whale2.txt, karena ini menghindari beberapa logika tambahan untuk menghitung baris baru.
sumber
C (gcc) ,
6797876528928476 byte,679619652740 tebakan salahCobalah online!
Pembaruan: ~ 27.000 poin dengan file yang diperbarui, 16 poin (8 byte) dengan fungsi yang lebih baik.
Penjelasan
Cara kerjanya adalah saat kode dijalankan melalui teks, kode tersebut menghafal karakter terakhir yang mengakhiri urutan 4 karakter yang diberikan, dan mengembalikan nilai tersebut. Agak mirip dengan pendekatan Arnauld di atas, tetapi bergantung pada kemungkinan inheren dari dua urutan 4-karakter yang diberikan mengakhiri dengan cara yang sama.
De-golf:
sumber
sh + bzip2, 2 * 364106 = 728212
2 * 381249 + 0 = 762498diikuti oleh whale2.txt bzip2-terkompresi dengan byte pertama hilang
Abaikan inputnya; menghasilkan jawaban yang benar. Ini memberikan garis dasar pada satu ujung; daniero memberikan garis dasar di ujung lainnya.
Skrip pembuat:
I / O test harness (tcc; potong baris pertama untuk gcc). Rangkaian uji ini dapat digunakan oleh siapa saja pada platform yang sesuai yang mengirimkan program lengkap yang mengharapkan baca / tulis I / O. Menggunakan byte / at-a-time I / O untuk menghindari kecurangan. Program anak harus flush output setelah setiap byte untuk menghindari pemblokiran.
sumber
but may not load any other external files, and your code may not access the whale.txt file in any way other than described above.
klausa?nth
waktu itu akan diberikan karakter ke-nwhale.txt
atauwhale2.txt
dan ia harus menampilkan tebakannya untuk(n+1)th
karakter." - Bagaimana persyaratan ini dipenuhi? Kode menampilkan seluruh tekswhale.txt
setiap kali dieksekusi.Python 3 , 879766
Cobalah online!
...
///
Jawaban yang mencetak spasi mendapat 10 upvotes, sedangkan kode saya hanya bisa mendapatkan 3 ...Penjelasan:
Untuk setiap karakter, program:
frequency[prev][char]
frequency[char]
yang memiliki skor total
Karena tidak ada cara untuk mengunggah file besar ke TIO (kecuali meminta Dennis), contoh dijalankan di tautan TIO hanya menjalankan program untuk sebagian kecil teks.
Dibandingkan dengan jawaban yang lebih lama, yang ini memiliki 362 karakter yang lebih salah, tetapi kode ini lebih pendek sebesar 255 byte. Pengganda membuat kiriman saya memiliki skor lebih rendah.
sumber
C #, 378 * 2 + 569279 = 570035
Pendekatan ini menggunakan tabel pencarian untuk mempelajari karakter paling umum yang mengikuti string yang diberikan. Kunci dari tabel pencarian memiliki maksimal 4 karakter, jadi fungsi pertama memperbarui tabel pencarian dengan karakter saat ini dan kemudian hanya memeriksa karakter mana yang paling mungkin terjadi setelah 4 yang sebelumnya termasuk yang saat ini . Jika 4 karakter itu tidak ditemukan dalam tabel pencarian, itu mencetak spasi.
Versi ini menggunakan
whale2.txt
file, karena sangat meningkatkan jumlah tebakan yang berhasil.Berikut ini adalah kode yang digunakan untuk menguji kelas:
Kode berjalan hanya dalam 2 detik. Sebagai catatan, inilah yang saya dapatkan ketika saya memodifikasi ukuran tombol dari tabel pencarian (termasuk hasil dari putaran kedua tanpa mengatur ulang model):
Akan menarik untuk mengetahui mengapa ukuran kunci 4 karakter adalah pilihan terbaik dalam algoritma ini.
Perbandingan teks
Asli:
Rekreasi:
Tebak:
Ubah log
whale2.txt
dan dengan demikian menghapus optimasi.sumber
Java 7, 1995 karakter, (1995 * 2 + 525158) 529148
Java menyebalkan untuk ukuran program kecil. Lagi pula, saya mencoba beberapa pendekatan yang sangat rumit dan rumit yang menghasilkan hasil omong kosong yang mengejutkan. Saya kemudian kembali dan hanya melakukan pendekatan sederhana, yang menghasilkan ukuran program yang lebih kecil dan hasil yang lebih baik.
Pendekatan ini sebenarnya sangat sederhana. Itu membabi buta memberi makan karakter x sebelumnya (di samping semua substring dari karakter tersebut) ke dalam hashtable, dipetakan ke karakter saat ini. Kemudian melacak pola mana yang paling akurat memprediksi karakter saat ini. Jika pola yang mendahului karakter tertentu ditemui berulang kali, mereka berhasil memprediksi karakter. Ini memberi prioritas pada string yang lebih panjang dan memberikan prioritas pada karakter apa pun yang paling sering mengikuti string yang diberikan. Algoritma ini tidak tahu apa-apa tentang jenis dokumen atau bahasa Inggris.
Saya memutuskan untuk menggunakan 9 karakter dan berusaha mencocokkan seluruh kata dalam 9 karakter sebelumnya jika memungkinkan. Ketika Anda tidak mencoba melakukan pencocokan kata dalam string, panjang optimal adalah 6 karakter, menghasilkan beberapa ribu kesalahan prediksi.
Satu pengamatan yang menarik adalah bahwa menggunakan 20 karakter menghasilkan prediksi buruk pertama kali melalui tetapi akurasi 99,9 persen pada lintasan berikutnya. Algoritma ini pada dasarnya mampu menghafal buku dalam tumpang tindih potongan 20 byte, dan ini cukup berbeda untuk memungkinkannya mengingat seluruh buku karakter dalam satu waktu.
sumber
Python 3,
2 × 497 + 619608 = 6206022 × 496 + 619608 = 620600Saya mencoba ini secara independen, tetapi berakhir dengan apa yang secara efektif merupakan versi yang lebih rendah dari jawaban Michael Homer. Saya harap itu tidak membuat jawaban saya sepenuhnya usang.
Ini membangun kamus kata-kata (didefinisikan secara kasar sebagai string yang diakhiri oleh
atau
\n
, case-sensitive dan termasuk tanda baca). Kemudian mencari kamus ini untuk kata-kata yang dimulai dengan apa yang sejauh ini diketahui dari kata saat ini, mengurutkan daftar yang dihasilkan berdasarkan frekuensi kemunculannya (perlahan-lahan), dan menebak bahwa karakter berikutnya adalah karakter berikutnya dalam kata yang paling umum yang cocok. Jika kami sudah memiliki kata yang cocok paling umum, atau tidak ada lagi kata yang cocok, itu kembali.
Ini juga membangun kamus pasangan kata yang menjijikkan dan tidak efisien. Setelah mencapai batas kata, ia menebak bahwa karakter berikutnya adalah huruf pertama dari kata kedua dalam pasangan kata yang paling umum cocok, atau
t
jika tidak ada yang cocok. Tapi itu tidak terlalu pintar. MengikutiMoby
, program dengan benar menebak bahwa karakter berikutnya adalahD
, tetapi kemudian ia melupakan semua konteksnya dan biasanya berakhir dengan memanggil paus "Moby Duck" (karena kata "Belanda" tampaknya lebih sering terjadi pada paruh pertama teks ). Akan mudah untuk memperbaikinya dengan memprioritaskan pasangan kata daripada kata-kata individual, tetapi saya berharap kenaikannya menjadi marginal (karena biasanya benar dari karakter ketiga aktif, dan pasangan kata tidak begitu membantu di tempat pertama).Saya bisa menyetel ini agar lebih cocok dengan teks yang disediakan, tapi saya tidak berpikir secara manual menyetel algoritma berdasarkan pengetahuan sebelumnya dari input benar-benar dalam semangat permainan jadi, selain memilih t sebagai karakter mundur setelah spasi ( dan saya mungkin juga seharusnya tidak melakukan itu), saya menghindarinya. Saya mengabaikan panjang baris yang diketahui dari file input, dan alih-alih dimasukkan
\n
setelah setiap 13 spasi — ini hampir pasti kecocokan yang sangat buruk, maksud utamanya adalah menjaga panjang garis masuk akal daripada untuk mencocokkan input.Kode tidak persis cepat (~ 2 jam di mesin saya), tetapi secara keseluruhan mendapat sekitar setengah karakter yang benar (49%). Saya berharap skor akan sedikit lebih baik jika dijalankan
whale2.txt
, tetapi saya belum melakukannya.Awal output terlihat seperti ini:
tetapi pada akhirnya, itu terlihat sedikit lebih seperti ... sesuatu. Bagian favorit saya dari dekat akhir buku ini,
keluar sebagai
Itu akan membuat The Wrath of Khan jauh lebih membingungkan. Dan "kesepian" → "geli" adalah substitusi yang sangat memuaskan.
Sunting: Disimpan satu byte dengan menghapus ruang yang asing
Mencetak gol
Ini menjalankan program untuk teks Moby Dick dan mengeluarkan teks "yang diprediksi" ke stdout, dan menyalahgunakan stderr untuk menulis skor. Saya akan merekomendasikan redirect output ke file.
sumber
lambda i:i[1]
lebih murah daripada berurusan denganoperator
?C ++, 2 · 62829 + 318786 = 444444
Untuk menjalankan program ini, Anda perlu file ini di sini , yang harus dinamai
C
.Program ini menggunakan kombinasi model Markov yang sama seperti pada jawaban kami sebelumnya . Seperti sebelumnya, kombinasi ini pada dasarnya adalah model dari jawaban ini oleh user2699 , tetapi dengan beberapa modifikasi kecil.
Melihat bagaimana jawaban ini menggunakan model yang sama persis seperti sebelumnya, perbaikan adalah mekanisme informasi-teori yang lebih baik daripada mekanisme "mundur" yang dijelaskan sebelumnya. Ini memungkinkannya untuk membuat lebih sedikit kesalahan sekaligus memiliki panjang gabungan yang lebih kecil. Program itu sendiri tidak banyak bermain golf karena ia bukan penyumbang utama skor.
Program ini panjangnya 2167 byte (termasuk semua tab untuk lekukan dan banyak karakter lain yang tidak perlu, tetapi sebelum kode uji), dan panjang file biner
C
adalah 60661 byte, jadi di bawah aturan untuk mencetak banyak file , kami mendapat skorL
2167 + 60661 + 1 = 62829.Program ini memakan waktu sekitar 8 menit untuk dijalankan pada sebuah
m5.4xlarge
instance di Amazon EC2 dan menggunakan sedikit lebih dari 16 GB memori. (Penggunaan memori berlebih ini tidak diperlukan - kami hanya tidak mengoptimalkannya juga.)sumber
Python 3, 526640
274 byte, 526092 kesalahan (menggunakan
whale2.txt
). Ini jelas mampu meningkatkan lebih lanjut, tetapi telah mencapai tahap "cukup baik untuk dikirim".Idenya adalah untuk menyimpan frekuensi semua menjalankan 2, 3, 4, ..., 10 karakter. Untuk setiap panjang L ini, kami memeriksa apakah karakter L-1 terbaru cocok dengan pola yang disimpan; jika demikian, tebakan kami g L adalah karakter berikutnya yang paling sering mengikuti pola itu. Kami mengumpulkan hingga sembilan tebakan dengan cara ini. Untuk memutuskan tebakan mana yang akan digunakan, kami menimbang frekuensi dari masing-masing pola berdasarkan panjangnya hingga kekuatan ke-8. Tebakan dengan jumlah frekuensi terbobot terbesar dipilih. Jika tidak ada pola yang cocok, kami menebak ruang.
(Panjang pola maksimum dan eksponen pembobotan dipilih oleh trial-and-error untuk memberikan tebakan salah yang paling sedikit.)
Ini versi work-in-progress ungolfed saya:
Dan test harness:
Berikut adalah beberapa contoh keluaran dari dekat awal teks. Sudah kita mulai melihat kemampuan untuk menyelesaikan kata-kata umum setelah melihat huruf pertama mereka (
in
,to
,and
,by
, juga, tampaknya,school
).Menjelang akhir, masih ada banyak kesalahan, tetapi juga banyak urutan yang sangat baik (
shmage seashawks
, misalnya).Sangat menarik untuk melihat beberapa kesalahan dan menebak kata apa yang "diharapkan" algoritma. Sebagai contoh, setelah itu
sail
, kedua program memprediksi -o
karenasailor
, saya kira. Atau lagi, setelah, a
mengharapkan -n
mungkin karena kejadian umum, and
.Changelog:
sumber
Python 2, skor: 2 * (407 + 56574) + 562262 = 676224
Mencari kata-kata yang cocok dengan karakter sebelumnya dari daftar
semuakata yang paling banyak digunakan dalam teks, diurutkan berdasarkan jumlah kemunculannya.Kode:
Data: https://www.dropbox.com/s/etmzi6i26lso8xj/d?dl=0
Test suite:
Sunting: Menggunakan
whale2.txt
memberi skor yang lebih baik.sumber
C ++ (GCC), 725 × 2 + 527076 = 528526
Namun pengajuan frekuensi awalan lainnya. Jalankan
whale2.txt
, dan dapatkan skor serupa (sedikit lebih buruk) dari yang lain.Yang ini dengan rakus menemukan string terpanjang yang dimulai dengan akhiran sejarah, dan jika ada banyak kandidat, tiebreak dengan string yang lebih pendek.
Sebagai contoh: Jika 7 karakter terakhir adalah
abcdefgh
, dan stringabcdefghi
danabcdefghj
muncul dengan frekuensi terbesar dalam semua string dari bentukabcdefgh*
, output akan baiki
atauj
, tiebreak dengan akhiran pendek (bcdefgh
,cdefgh
, ...).Untuk alasan yang tidak diketahui, apapun lebih dari 7 dan komputer saya tidak memiliki cukup RAM untuk menjalankannya. Bahkan dengan 7, saya harus menutup semua browser web untuk menjalankannya.
Kode pengujian:
Tidak Terkumpul:
Contoh output:
Yang ini dekat akhir teks. Kebanyakan kata-kata panjang diperkirakan cukup akurat (
intervals
,pivot-hole
,distance
)Huruf besar sepertinya tidak baik.
sumber
Python 2, 756837
Menggunakan sesuatu yang mungkin rantai Markov?
sumber
zlib.decompress('...')
dievaluasi menjadi{'G?':' ', 'G;':' ','G"':' ',.......}
, dana
merupakan kamus yang memetakan dari 2 karakter ke 1 karakter. Pada dasarnya varian 2-karakter dari jawaban Steadybox .xxd
,hexdump
,uuencode
, Atau serupaHaskell, (1904 + 1621 + 208548 + 25646) * 2 + 371705 = 847143
Contoh:
Menggunakan tiga file tambahan yang dihitung sebelumnya:
seqwords
berisi 236 kata yang paling umum.wordsseq
berisi sekuens terkompresi LZMA dari kata-kata ini, dan untuk semua kata yang bukan di antara 236 paling umum, panjangnya.dicttries
berisi, untuk setiap panjang kata, pohon keputusan yang berisi semua kata yang tersisa. Dari percobaan ini, entri dipilih saat kita melanjutkan.Dengan cara ini, kami mencapai tingkat kesalahan yang jauh lebih rendah daripada semua skema lossy lainnya; Sayangnya,
wordsseq
file tersebut masih terlalu besar untuk bisa bersaing.Berikut ini adalah versi lengkap yang membuat file dan melakukan analisis:
sumber
C ++ (WIP), 1923 * 2 + 1017344 = 1021190
Saat ini, solusi ini adalah WIP dan karena itu tidak ungolfed. Juga mempertimbangkan bahwa ukuran kode aktual hampir tidak memiliki dampak pada skor saya pikir saya memposting jawaban saya terlebih dahulu sebelum mulai mengoptimalkan mikro itu.
(Kode lengkap tersedia di sini: https://github.com/BrainStone/MobyDickRNG - Termasuk program lengkap dan pencarian unggulan)
Solusi ini didasarkan pada RNG. Pertama saya menganalisis teks. Saya membuat peta yang menghitung kemunculan dua karakter berurutan. Lalu saya membuat peta distribusi. Ini semua dilakukan secara statis sehingga harus sesuai dengan aturan.
Kemudian ketika mencoba untuk mencetak teks saya melakukan pencarian dan menarik karakter acak yang mungkin. Meskipun ini biasanya menghasilkan hasil yang lebih buruk daripada hanya menghasilkan surat berikut yang paling umum, mungkin ada benih dewa yang akan menghasilkan hasil yang lebih baik. Itu sebabnya benih tersebut dikodekan dengan keras. Saat ini saya sedang mencari benih terbaik. Dan saya akan memperbarui jawaban ini setelah saya menemukan benih yang lebih baik. Jadi tetaplah diposting!
Jika ada yang ingin mencari benih sendiri atau menggunakan RNG berbeda jangan ragu untuk membayar repo.
Metode yang digunakan untuk menghitung skor: https://github.com/BrainStone/MobyDickRNG/blob/master/src/search.cpp#L15
Catatan meskipun skor total adalah yang terburuk saat ini, itu mengalahkan hitungan kesalahan hanya menghasilkan ruang. Dan kemungkinan bagus bahwa skor akan turun, dengan memeriksa lebih banyak benih.
Changelog
Biji yang diperiksa: 0-50000. Nilai: 2305 * 2 + 1017754 = 1022364
Benih yang diperiksa: 0-80000. Nilai: 1920 * 2 + 1017754 = 1021594 (-770)
Benih yang diperiksa: 0-32000000. Nilai: 1923 * 2 + 1017344 = 1021190 (-404)
sumber
Ruby, 1164418 (aduh)
Saya hanya ingin melihat seberapa baik yang bisa saya lakukan tanpa memeriksa jawaban lain.
Saya tidak yakin apakah ini diperbolehkan karena itu termasuk literal yang saya hasilkan dengan menganalisis file, tetapi meskipun tidak, itu tidak seperti itu dalam bahaya mengalahkan siapa pun.
Bagaimana saya menghasilkan
x
Pertama, saya membuat
a.txt
dengan yang berikut ini:Lalu saya menghasilkan
a.csv
:Lalu saya menguraikannya
x
dengan skrip Ruby berikut:Bagaimana saya mencetak gol
sumber
Python 3 , (146 * 2 + 879757) 880049 byte
Cobalah online!
Tabel frekuensi cukup mudah. Setiap posisi dalam string sesuai dengan kode ascii karakter saat ini (minus 10 = 0x0a = '\ n', karakter terendah dalam file), dan karakter pada setiap indeks adalah karakter berikutnya yang paling sering. Dengan asumsi saya menghitung frekuensi dengan benar ...
Diuji dengan kode dari tes user202729
sumber
def f(c):return(" ">c)*c or"t ... e"[ord(c)-32]
?[Python 3] (644449 * 2 + 0) 1288898 poin
Akurasi sempurna hanya dalam 644449 byte
Kode lengkap tidak dapat ditampung dalam jawaban, jadi saya telah meletakkannya di sini dan mengganti literal string biner besar dengan b '###' dalam teks jawaban.
Ini dihasilkan dengan kode berikut, di mana "modified.py" adalah file yang dihasilkan, dan "cheatsheet.txt" adalah file whale2.txt mulai dari karakter kedua.
Kode dapat dieksekusi dengan menambahkan berikut ini di akhir "modified.py". "whale2.txt" harus berada di direktori yang sama dengan "modified.py", dan hasilnya akan ditulis ke "out.txt".
Jawaban ini tidak secara langsung mengakses whale.txt atau whale2.txt. Itu menggunakan perpustakaan kompresi standar yang ada secara eksplisit diizinkan dalam aturan.
sumber