Tantangan
Tulis program yang mengkompres dan mendekompresi teks ASCII tanpa kehilangan. Ini harus dikhususkan untuk bekerja dengan baik dengan palindrom, termasuk palindrom yang tidak peka huruf besar dan kecil. Kompresi terbaik dengan sumber terkecil menang.
Mencetak gol
total_bytes_saved / sqrt(program_size)
- Kemenangan skor tertinggi
total_bytes_saved
adalah berapa banyak byte lebih kecil dari string yang dikompresi daripada aslinya, total di seluruh test case di bawah ini. program_size
adalah ukuran dalam byte kode sumber dari kedua program kompresi dan dekompresi. Kode yang dibagikan di antara keduanya hanya perlu dihitung satu kali.
Misalnya, jika ada 10 kasus uji dan program 100 byte menyelamatkan 5 byte pada 7 kasus uji, masing-masing 10 dari 2 kasus, tetapi kasus uji terakhir 2 byte lebih lama, solusinya akan mencetak 5,3. ( (7 * 5 + 10 * 2 - 2) / sqrt(100) = 5.3
)
Uji Kasus
tacocat
toohottohoot
todderasesareddot
amanaplanacanalpanama
wasitacaroracatisaw?
Bob
IManAmRegalAGermanAmI
DogeeseseeGod
A Santa at NASA
Go hang a salami! I'm a lasagna hog.
Aturan
- Celah standar berlaku.
- Kompresi harus bekerja pada semua string teks ASCII (byte 32-126, inklusif) yang dapat dicetak, bukan hanya palindrom. Namun sebenarnya tidak perlu menghemat ruang untuk input apa pun.
- Output dapat berupa urutan byte atau karakter, terlepas dari implementasinya atau representasi internal (string, daftar, dan array adalah semua permainan yang adil, misalnya). Jika penyandian ke UTF-8, hitung byte, bukan karakter. String lebar (mis. UTF-16 atau UTF-32) tidak diizinkan kecuali jika satu-satunya codepoint yang mungkin digunakan adalah antara 0 dan 255.
- Kompresi / dekompresi bawaan tidak diizinkan.
Demi kesenangan kita sendiri, posting string terkompresi dengan kode sumber Anda.
UPDATE 1: Skor berubah dari total_bytes_saved / program_size
menjadi total_bytes_saved / sqrt(program_size)
untuk memberi lebih banyak bobot untuk kompresi yang lebih baik dan lebih sedikit berat untuk golf agresif. Sesuaikan skor Anda sesuai.
UPDATE 2: diperbaiki wasitacaroraratisaw?
menjadiwasitacaroracatisaw?
sumber
wasitacaroraratisaw?
ini adalah contoh tandingan untuk itu[32-126]
?1000 *
bagian itu benar-benar diperlukan, dan tidak, saya tidak berpikir itu akan membuat skor terasa lebih "memuaskan";)Jawaban:
JavaScript (ES6), 3,143 (81 byte disimpan, 664 byte program)
Sekarang saya cukup puas dengan program ini (dan sistem penilaian), saya akan menulis sedikit penjelasan.
Ide dasarnya adalah untuk mengompresi input ke dalam string bit, kemudian kompres setiap set 8 bit menjadi byte. Untuk keperluan penjelasan, saya hanya akan memanipulasi string bit.
String bit dapat dipisahkan menjadi beberapa bagian:
Header adalah pemetaan yang sangat sederhana:
Data surat juga cukup sederhana. Pertama, semua non-huruf diekstraksi dari string, dan semua huruf dikonversi menjadi huruf besar. Jika string yang dihasilkan adalah palindrom, bagian yang dibalik dilucuti. Kemudian pemetaan ini diterapkan:
Bagian ini diakhiri dengan
111
. Setelah itu muncul data styling, yang menyimpan data huruf besar / kecil dan non-huruf. Ini berfungsi seperti ini:Jadi melalui contoh yang ditunjukkan di atas, kami punya
Ketika akhir string bit tercapai, semua karakter yang tersisa dari data huruf ditambahkan ke hasilnya. Ini menyelamatkan kita dari keharusan melakukan yang terakhir
000...001
dan memungkinkan kita untuk memotong bit-bit ini dari string.Mengalami kasus uji:
sumber
Bob
juga.Bob
benar-benar jatuh ke tempatnya - 1 bit untuk header, 10 + 3 bit untuk dua huruf, dan 2 bit untuk huruf besar tunggal. Tidak bisa lebih pendek jika saya berusaha sekuat tenaga ...-0+9
+9
akan setuju dengan string, sementara-~8
akan melakukan+9
aritmatika (karena-
tidak melakukan apa pun untuk string, jadi itu menafsirkannya sebagai angka). Dalam hal-~8
ini cukup pintar. :) Jawaban bagus btw, +1 dari saya! Sangat pintar menyimpan semua informasi dalam bit seperti itu, bahkan menghemat satu byteBob
.Python 2: 2.765 (70 byte disimpan, program 641 byte)
Saya mengubah pendekatan saya sedikit. Sekarang bekerja dengan baik pada palindrom yang tidak sempurna. Tidak ada string terkompresi yang akan lebih panjang dari input. Palindrom panjang rata yang sempurna akan selalu kompres hingga 50% dari ukuran aslinya.
Hasil
Dan sebagai bonus, menghemat 6 byte pada palindrome yang salah yang saya miliki sebelumnya.
Penjelasan
Dekompresi menggunakan stack. Codepoints dari 32-127 diperlakukan secara harfiah. Jika karakter adalah huruf, nilai didorong ke tumpukan juga. Nilai 128-192 digunakan untuk huruf terbalik, sehingga huruf terbalik (
o^32
karena bagaimana ASCII diletakkan) akan didorong ke tumpukan dan huruf normal akan ditambahkan ke string. Nilai 192-255 digunakan untuk menambahkan huruf tanpa mendorong ke tumpukan, jadi ini digunakan ketika huruf tidak cocok dan untuk huruf tengah dalam palindrom panjang aneh. Codepoints 1-15 menunjukkan bahwa tumpukan harus muncul beberapa kali. Codepoints 17-31 serupa, tetapi mereka mencetak spasi terlebih dahulu sebelum muncul dari tumpukan. Ada juga instruksi "pop hingga kosong" implisit di akhir input.Kompresor bekerja dari kedua ujung dan lipatan dalam huruf yang cocok sebagai nilai 1-31. Itu melompati non-huruf. Ketika huruf cocok tetapi kasingnya tidak, itu menambahkan 64 ke huruf kiri dan menambah huruf kanan. Ini memungkinkannya menghemat ruang
IManAmRegalAGermanAmI
. Di bagian tengah atau ketika huruf-hurufnya tidak cocok, huruf itu berada di kedua sisi. Saya tidak dapat menambahkan di sana karena saya perlu menghindari kasus khusus di manaleft == right
. Ketika melipat spidol tetangga di sisi kanan, saya harus memeriksa bahwa spanduk tetangga tidak akan meluap ke codepoint 16 karena saya membutuhkannya untuk spasi. (Ini sebenarnya bukan masalah bagi string kasus uji apa pun)EDIT 1 : Tidak ada lagi versi ungolfed.
sumber
Python3, 1,833 (25 byte disimpan, program 186 byte)
Pengodean entropi probabilitas-sama dengan probabilitas-0 yang sederhana. Tidak ada optimasi spesifik palindrome.
sumber
Java 8, skor: 1,355 (20 byte disimpan / 218 (107 + 111) byte)
Fungsi kompres (berisi tiga karakter ASCII yang tidak dapat dicetak):
Fungsi dekompresi (berisi dua karakter ASCII yang tidak dapat dicetak):
Penjelasan:
Cobalah online.
Hanya kompres palindrom yang sempurna.
sumber