Misi Anda hari ini adalah menciptakan kompresor teks.
Tugas
Anda akan menulis dua fungsi:
The packer adalah fungsi yang menerima sebuah string karakter ASCII (U + 0000 untuk U + 007F) dan output string Unicode (U + 0000 untuk U + 10FFFF), yang berisi karakter yang mungkin paling sedikit.
The unpacker adalah fungsi yang menerima sebuah Unicode string disandikan dan output persis ASCII string asli.
Memasukkan
Satu-satunya input yang diotorisasi adalah string ASCII (untuk pengemas) dan string Unicode yang dikemas (untuk pengurai). Tidak ada input pengguna, tidak ada koneksi internet, tidak ada penggunaan sistem file.
Fungsi Anda dapat memiliki akses ke daftar kata-kata bahasa Inggris ini . Anda dapat menggunakan daftar ini sebagai file txt lokal, atau menyalin kontennya dalam kode sumber Anda sebagai string atau array string .
Anda tidak dapat menyalin kode snippet di bawah ini di fungsi Anda.
Keluaran
Satu-satunya keluaran resmi untuk kedua fungsi adalah string.
Output dari unpacker harus mengandung karakter yang persis sama dengan input dari packer.
Input dan output Anda dapat menggunakan pengkodean karakter apa pun yang mendukung semua Unicode (UTF-8/16/32, GB18030, ...), karena skor Anda hanya akan bergantung pada jumlah karakter Unicode dalam output. Harap pastikan pengkodean mana yang Anda gunakan.
Untuk menghitung jumlah karakter Unicode dalam output Anda, Anda dapat menggunakan alat ini: http://mothereff.in/byte-counter
Mencetak gol
Entri Anda harus dapat mengemas dan membongkar 10 cuplikan teks berikut (yang saya ambil di forum ini).
Skor Anda akan menjadi jumlah dari ukuran 10 string Anda (dalam karakter Unicode) + ukuran dua fungsi Anda (dalam karakter Unicode juga)
Jangan hitung ukuran kamus jika Anda menggunakannya.
Harap sertakan di dalam entri Anda "skor" dari setiap cuplikan dan versi dikemasnya.
Skor terendah menang.
Data
Berikut ini cuplikan untuk disandikan untuk menghitung skor Anda:
1: Lirik Rick Roll (1870b): Kami tidak asing dengan kode golf, Anda tahu aturannya, dan saya juga
Kami bukan orang asing untuk dicintai Anda tahu aturannya dan saya juga Komitmen penuh adalah apa yang saya pikirkan Anda tidak akan mendapatkan ini dari pria lain Aku hanya ingin memberitahumu bagaimana perasaanku Harus membuatmu mengerti Tak akan menyerahkanmu Tidak akan pernah mengecewakan Anda Tidak akan pernah berlari dan meninggalkanmu Tidak akan pernah membuatmu menangis Tidak akan pernah pamit Tidak akan pernah berbohong dan menyakitimu Kami sudah saling kenal begitu lama Hatimu sakit tapi Kamu terlalu malu untuk mengatakannya Di dalam kita berdua tahu apa yang sedang terjadi Kami tahu permainannya dan kami akan memainkannya Dan jika Anda bertanya bagaimana perasaan saya Jangan bilang kamu terlalu buta untuk melihat Tak akan menyerahkanmu Tidak akan pernah mengecewakan Anda Tidak akan pernah berlari dan meninggalkanmu Tidak akan pernah membuatmu menangis Tidak akan pernah pamit Tidak akan pernah berbohong dan menyakitimu Tak akan menyerahkanmu Tidak akan pernah mengecewakan Anda Tidak akan pernah berlari dan meninggalkanmu Tidak akan pernah membuatmu menangis Tidak akan pernah pamit Tidak akan pernah berbohong dan menyakitimu (Ooh, menyerahlah) (Ooh, menyerahlah) (Ooh) Tidak akan pernah memberi, tidak akan pernah memberi (Menyerah) (Ooh) Tidak akan pernah memberi, tidak akan pernah memberi (Menyerah) Kami sudah saling kenal begitu lama Hatimu sakit tapi Kamu terlalu malu untuk mengatakannya Di dalam kita berdua tahu apa yang sedang terjadi Kami tahu permainannya dan kami akan memainkannya Aku hanya ingin memberitahumu bagaimana perasaanku Harus membuatmu mengerti Tak akan menyerahkanmu Tidak akan pernah mengecewakan Anda Tidak akan pernah berlari dan meninggalkanmu Tidak akan pernah membuatmu menangis Tidak akan pernah pamit Tidak akan pernah berbohong dan menyakitimu Tak akan menyerahkanmu Tidak akan pernah mengecewakan Anda Tidak akan pernah berlari dan meninggalkanmu Tidak akan pernah membuatmu menangis Tidak akan pernah pamit Tidak akan pernah berbohong dan menyakitimu Tak akan menyerahkanmu Tidak akan pernah mengecewakan Anda Tidak akan pernah berlari dan meninggalkanmu Tidak akan pernah membuatmu menangis Tidak akan pernah pamit Tidak akan pernah berbohong dan menyakitimu
2: Golfer (412b): Golf-ASCII-art
'\. . |> 18 >> \. ' | O >>. 'o | \. | / \. | / /. ' | jgs ^^^^^^ `^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^
3: the number diamond (233b): Cetak berlian ini
1 121 12321 1234321 123454321 12345654321 1234567654321 123456787654321 12345678987654321 123456787654321 1234567654321 12345654321 123454321 1234321 12321 121 1
4: alfabet empat kali (107b): Cetak alfabet empat kali
abcdefghijklmnopqrstuvwxyz qwertyuiopasdfghjklzxcvbnm pyfgcrlaoeuidhtnsqjkxbmwvz zyxwvutsrqponmlkjihgfedcba
5: Lirik Old McDonald's (203b): Fungsi Old MacDonald
Old MacDonald memiliki sebuah peternakan, EIEIO, Dan di peternakan itu dia punya seekor sapi, EIEIO, Dengan moo moo di sini dan moo moo di sana, Di sini moo, ada moo, di mana-mana moo moo, Old MacDonald punya pertanian, EIEIO!
6: Lirik Rock around the clock (144b): Rock Around the Clock
1, 2, 3 jam, 4 jam rock, Jam 5, 6, 7, jam 8, Jam 9, 10, 11, jam 12 siang, Kami akan nge-rock sepanjang waktu malam ini.
7: Hello World (296b): Katakan "Halo" kepada dunia dalam seni ASCII
_ _ _ _ _ _ _ | | | | ___ | | | ___ __ _____ _ __ | | __ | | | | | _ | | / _ \ | | / _ \ \ \ / \ / / _ \ | '__ | | / _` | | | _ | __ / | | (_) | \ VV / (_) | | | | (_ | | _ | | _ | | _ | \ ___ | _ | _ | \ ___ () \ _ / \ _ / \ ___ / | _ | | _ | \ __, _ (_) | /
8: Berkat Irlandia (210b): An Old Irish Blessing
Semoga kita menemukan jalan untuk bertemu Semoga angin selalu ada di belakang Anda Semoga matahari menyinari wajah Anda Hujan turun lembut di ladang Anda Dan sampai kita bertemu lagi Semoga Tuhan memegang Anda di lekukan tangan-Nya
9: Ada lirik wanita tua (1208b): Ada Wanita Tua
Ada seorang wanita tua yang menelan lalat. Saya tidak tahu mengapa dia menelan lalat itu, Mungkin dia akan mati. Ada seorang wanita tua yang menelan laba-laba, Itu menggeliat dan bergoyang-goyang dan berguncang di dalam dirinya. Dia menelan laba-laba untuk menangkap lalat, Saya tidak tahu mengapa dia menelan lalat itu, Mungkin dia akan mati. Ada seorang wanita tua yang menelan seekor burung, Betapa absurdnya menelan burung. Dia menelan burung itu untuk menangkap laba-laba, Dia menelan laba-laba untuk menangkap lalat, Saya tidak tahu mengapa dia menelan lalat itu, Mungkin dia akan mati. Ada seorang wanita tua yang menelan seekor kucing, Bayangkan itu menelan seekor kucing. Dia menelan kucing itu untuk menangkap burung itu, Dia menelan burung itu untuk menangkap laba-laba, Dia menelan laba-laba untuk menangkap lalat, Saya tidak tahu mengapa dia menelan lalat itu, Mungkin dia akan mati. Ada seorang wanita tua yang menelan seekor anjing, Betapa babi harus menelan seekor anjing. Dia menelan anjing itu untuk menangkap kucing itu, Dia menelan kucing itu untuk menangkap burung itu, Dia menelan burung itu untuk menangkap laba-laba, Dia menelan laba-laba untuk menangkap lalat, Saya tidak tahu mengapa dia menelan lalat itu, Mungkin dia akan mati. Ada seorang wanita tua yang menelan seekor kuda, Dia meninggal tentu saja.
10: alamat gettysburg (1452b): Seberapa acak Alamat Gettysburg
Empat skor dan tujuh tahun yang lalu ayah kita menghasilkan di benua baru ini sebuah negara baru, diciptakan dalam kebebasan, dan didedikasikan untuk proposisi bahwa semua manusia diciptakan sama. Sekarang kita terlibat dalam perang saudara yang hebat, menguji apakah negara itu, atau negara mana pun yang dikonsep dan begitu berdedikasi, dapat bertahan lama. Kita bertemu di medan perang yang hebat. Kami datang untuk mendedikasikan sebagian dari ladang itu, sebagai tempat peristirahatan terakhir bagi mereka yang di sini memberikan hidup mereka agar bangsa itu bisa hidup. Sangat tepat dan patut kita melakukan ini. Tetapi, dalam arti yang lebih besar, kita tidak bisa mendedikasikan, kita tidak bisa menguduskan, kita tidak bisa menguduskan tanah ini. Orang-orang pemberani, hidup dan mati, yang berjuang di sini, telah menguduskannya, jauh di atas kekuatan buruk kita untuk menambah atau mengurangi. Dunia akan sedikit memperhatikan, atau lama mengingat apa yang kita katakan di sini, tetapi tidak pernah bisa melupakan apa yang mereka lakukan di sini. Bagi kami yang hidup, lebih tepatnya, didedikasikan di sini untuk pekerjaan yang belum selesai yang sejauh ini telah mereka perjuangkan dengan begitu mulia. Adalah lebih baik bagi kita untuk berada di sini didedikasikan untuk tugas besar yang tersisa di hadapan kita - bahwa dari orang-orang mati yang terhormat kita semakin meningkatkan pengabdian kepada sebab yang mereka berikan ukuran penuh terakhir dari pengabdian - bahwa kita di sini sangat memutuskan bahwa orang-orang mati ini tidak akan telah mati sia-sia - bahwa bangsa ini, di bawah Tuhan, akan memiliki kelahiran baru yang bebas - dan bahwa pemerintahan rakyat, oleh rakyat, untuk rakyat, tidak akan binasa dari bumi.
Total (tidak terkompresi): 6135 karakter / byte.
Selamat bersenang-senang!
private static final String RICK_ROLL_RETURN = "We're no strangers to love...
Jawaban:
Haskell - 5322 poin
Byte kode:
686
Ukuran asli :
6147
= 1871+415+234+108+204+145+297+211+1209+1453
Ukuran yang dikodekan:
4636
= 1396+233+163+92+153+115+197+164+979+1144
Skor:
686+ 4636
Kompresi jumlah karakter:
~25%
Kode
Selain optimasi, ini menyimpan nilai antara
0
dan7f
dalam karakter unicode sebagai faktor utama mereka.Itu tidak menurunkan jumlah byte dari output yang disandikan, itu hanya menurunkan jumlah karakter unicode. Misalnya, uji # 4 berisi
108
karakter dan output yang disandikan92
,. Namun ukuran masing-masing108
dan364
byte.Bagaimana itu bekerja
Pengkodean
n
.n
kemudian dikonversi menjadi daftar faktor utamanyaps
,.1
. Ini berarti mereka, faktor-faktornya, dapat disimpan sebagai indeks hanya dengan 5 bit.1
adalah kasus khusus dan diwakili oleh daftar kosong.ps
encoding sekarang dapat mulai.ps
dikonversi menjadi indeks dalam daftar 32 faktor unik (Dalam kode di atas daftar ini diidentifikasi sebagaia
).ps
perlu diratakan. Untuk menjaga integritas data, setiap daftar diubah menjadi daftar dua bagian lainnyafs
,.fs
kemudian dapat dikemas ke dalam karakter unicode menggunakan bit shifting.Decoding
1
cocok ini, saya ingin mengingatkan Anda tentang ituproduct [] == 1
.Tes
Menggunakan antarmuka ini untuk pengujian akan menyakitkan, jadi saya menggunakan fungsi ini untuk memberikan hasil di bawah ini.
Mencicipi
Output dari fungsi encoding
g
untuk test # 4 adalah ini"\99429\582753\135266\70785\35953\855074\247652\1082563\68738\49724\164898\68157\99429\67973\1082404\587873\73795\298017\330818\198705\69861\1082435\595009\607426\36414\69873\855074\265249\346275\67779\68738\77985\1082513\821353\132131\101410\247652\1082562\49724\164898\67649\594977\34915\67746\50273\135265\103997\563265\103457\1086021\99399\584802\70753\73889\34882\582722\411459\67779\68740\1084516\1082563\1091681\103491\313282\49724\164897\68705\135741\69858\50241\607426\35905\608421\1082435\69858\50274\71777\43075\298018\280517\1082404\67971\36017\955425\67665\919600\100452\132129\214883\35057\856097\101474\70753\135737"
atau jika Anda mahir omong kosong, ini
𘑥𡁢𑒁豱𐲂숼𨐢𘑥𐦅𒁃𰠱𑃥踾𑃱𐲂𓂡𠐣𘰢숼𨐢𐡁衣쑡𡁡𘑇𑑡𒂡衂𐲄숼𨐡𡈽𑃢쑁豁𑃢쑢ꡃ𐦃貱𐡑𘡤𠐡裱𘱢𑑡𡈹
Catatan tambahan
edTest
ukuran tes semuanya konsisten tetapi masih berbeda dari ukuran yang ditunjukkan dalam pertanyaan.—
) bahwa saya diganti dengan-
karena mereka berada di luar0
-7f
jangkauan.00
casing dasar,01
ulangi semua,10
ulangi kecuali yang terakhir,11
ulangi kecuali dua yang terakhir.sumber
abcdefghijklm...
ke𘑥𡁢𑒁豱...
, bisa Anda jelaskan sedikit lebih lanjut silahkan? Juga, saya telah memperbaiki jumlah char dan mengonversikan em-dash di # 10, dalam pertanyaan. Jumlah char saya masih berbeda dari milik Anda. Entah mengapa, saya menggunakan alat mothereff.in.C ++ (C ++ 11), 2741 poin
Jawaban ini menggunakan UTF-32 sebagai pengodean untuk teks yang dikompresi.
Char menghitung dan mencetak gol
Kode: 593 karakter (baris baru tertinggal dilepaskan)
Teks terkompresi (karakter unicode) : 654 + 145 + 82 + 38 + 51 + 104 + 73 + 423 + 506 = 2148 (dihitung dengan
wc -m
jumlah karakter unicode daripada byte, jumlah byte adalah, seperti halnya dengan jawaban @ gxtaillon , lebih tinggi dari aslinya, 8413 byte total, sebagaimana dihitung denganwc -c
).Rasio kompresi (ASCII ke unicode) : 35,01% (menggunakan 6135 byte dari pertanyaan (sama seperti
wc -c
))Waspadalah:
Banyak shell tidak dapat menangani karakter unicode yang dihasilkan oleh program ini. Dengan demikian, dekompresi dapat menyebabkan teks terputus di suatu tempat ketika shell tidak dapat menangani karakter, karena input diambil melalui
stdin
dari shell.Kompilasi
Ini harus dikompilasi dengan
clang++
dang++ -std=c++11
, tetapi akan menampilkan beberapa peringatan tentang prioritas operator, karena ekspresi sepertib<<20-n&0xFFFFF
tidak akan diperlakukan sebagai((b << 20) - n) & 0xFFFFF
, seperti yang diharapkan, tetapi sebagai(b << (20 - n)) & 0xFFFFF
.Pemakaian
./compress
../compress c
untuk kompres atau./compress d
dekompresi. (Hati-hati, meninggalkan opsi memberi SEGFAULT (pengecekan kesalahan sangat mahal ...) dan opsi lainnya (seperti menggunakanD
alih-alih menggunakand
) dapat memberikan hasil yang tidak terdugastdin
dan output ditulis kestdout
Bagaimana itu bekerja
Tidak disatukan
Penjelasan
Karena semua karakter unicode dari
U+0000
hinggaU+10FFFF
diizinkan, kami dapat menggunakan 20 bit per karakter unicode:U+FFFFF
menggunakan 20 bit dan masih termasuk dalam rentang yang diizinkan. Jadi, kami hanya mencoba menjejalkan semua bit karakter ASCII individu ke dalam karakter unicode untuk menyimpan beberapa karakter ASCII dalam satu karakter unicode. Namun, kita juga perlu menyimpan jumlah bit yang digunakan dalam karakter unicode terakhir, karena bit sampah yang tidak digunakan dapat ditafsirkan sebagai karakter ASCII terkompresi yang tepat. Karena jumlah maksimum bit yang digunakan dalam karakter unicode terakhir adalah 20, kita akan membutuhkan 5 bit untuk itu, yang ditempatkan di awal data terkompresi.Contoh output
Ini adalah output misalnya # 4 (seperti yang diberikan oleh
less
):(
쏏𦛏
berikan<U+C3CF><U+266CF>
sebagai kode karakter, tapi saya mungkin salah)sumber
Python 3, 289 + 818 = 1107 poin
Hanya golf ringan.
Ukuran kode total adalah 289 byte, dan mengkodekan 6135 byte yang diberikan ke 818 karakter Unicode - jumlah total output byte adalah 3201 byte, jauh lebih kecil dari input asli.
Mengkodekan menggunakan zlib, kemudian menggunakan pengkodean unicode. Beberapa logika tambahan diperlukan untuk menghindari pengganti (yang Python benar-benar benci).
Contoh output dari # 4, seperti yang terlihat oleh
less
(37 karakter Unicode):Program driver untuk pengujian:
Hitungan byte keluaran:
sumber
p
adalah pembungkusnya,u
adalah pembongkar bungkusnya .Python 2 - 1141 poin
Ukuran kode adalah
281
byte dan mengkodekan6135
byte ke860
karakter unicode.Bagaimana itu bekerja:
Untuk Menyandikan:
19
bit, tambahkan1
sedikit ke awal masing-masing, dan kemudian dikonversi ke karakter Unicode.Decoding adalah kebalikannya.
Perhatikan bahwa beberapa versi python hanya dapat menangani karakter unicode hingga
0xFFFF
, dan dengan demikian kode ini akan menaikkan aValueError
.sumber