Sebuah Latin persegi adalah persegi yang ada telah berulang simbol dalam baris atau kolom: .
13420
21304
32041
04213
40132
Dan seperti yang diketahui banyak pemain Sudoku, Anda tidak perlu semua angka untuk menyimpulkan angka yang tersisa.
Tantangan Anda adalah untuk mengompresi kotak Latin ke dalam byte sesedikit mungkin. Anda perlu menyediakan satu atau dua program yang mengkompres / mendekompresi.
Berbagai info:
- Angka-angka yang digunakan akan selalu berada
0..N-1
, di manaN
panjang tepi kotak, danN<=25
- Pada dekompresi, kotak latin harus identik dengan input.
- Program Anda harus dapat (de) mengompres setiap kotak latin (dalam ukuran kotak maksimum), bukan hanya yang saya sediakan. Rasio kompresi juga harus serupa.
- Anda benar-benar harus menjalankan kompresi dan dekompresor untuk mendapatkan skor Anda (Tidak ada runtime akhir zaman)
Kasing uji dapat ditemukan di github . Skor Anda adalah ukuran total dari kasus uji terkompresi.
EDIT: Pada 20:07 pada tanggal 7 Juli, saya memperbarui kasus uji (untuk memperbaiki masalah generasi). Silakan jalankan kembali program Anda pada kasus uji baru. Terima kasih Anders Kaseorg .
code-challenge
compression
Nathan Merrill
sumber
sumber
0
meskipunn-1
:)n
simbol yang berbeda. : PJawaban:
Python,
1281.3751268.625 byteKami menyandikan satu "keputusan" dalam kotak Latin pada satu waktu, di mana setiap keputusan dari salah satu dari tiga bentuk ini:
Pada setiap langkah, kami membuat semua kesimpulan logis yang kami dapat berdasarkan pada keputusan sebelumnya, lalu mengambil keputusan dengan jumlah pilihan sekecil mungkin, yang karenanya mengambil jumlah bit terkecil untuk diwakili.
Pilihan disediakan oleh dekoder aritmatika sederhana (div / mod dengan jumlah pilihan). Tapi itu meninggalkan beberapa redundansi dalam pengkodean: jika k decode ke kotak di mana produk dari semua jumlah pilihan adalah m , maka k + m , k + 2⋅ m , k + 3⋅ m , ... decode ke kotak yang sama dengan beberapa kondisi sisa di akhir.
Kami memanfaatkan redundansi ini untuk menghindari penyandian ukuran persegi secara eksplisit. Dekompresor dimulai dengan mencoba men-decode kuadrat ukuran 1. Setiap kali decoder selesai dengan status sisa, ia membuang hasil itu, mengurangi m dari angka asli, menambah ukurannya dengan 1, dan mencoba lagi.
Keluaran:
sumber
np.stack()
. Dalam hal ini dapat diganti dengannp.array([…])
, dan saya telah melakukannya dalam versi saat ini.MATLAB,
3'062.52'888.125 bytePendekatan ini hanya menghilangkan baris terakhir dan kolom terakhir dari bujur sangkar, dan mengubah setiap entri menjadi kata-kata dengan kedalaman bit tertentu. Kedalaman bit dipilih minimal untuk ukuran persegi yang diberikan. (Saran oleh @KarlNapf) Kata-kata ini hanya ditambahkan satu sama lain. Dekompresi hanyalah kebalikannya.
Jumlah untuk semua kasus uji adalah 23'105 bit atau 2'888,125 byte. (Masih berlaku untuk kasus uji yang diperbarui, karena ukuran output saya hanya tergantung pada ukuran input.)
sumber
n=9..16
4 bit sudah cukup.Python 3, 10772 bit (1346,5 byte)
Memakan waktu 0,1 detik untuk mengompresi dan mendekompres kasus uji kombinasi.
Verifikasi skor di Ideone .
sumber
len(possible)
is 1 andpossible.index(rows[i][j])
is 0, so that symbol is encoded at no cost.J, 2444 bytes
Relies on the builtin
A.
to convert to and from a permutation of integers [0, n) and a permutation index.Compress, 36 bytes
The input is a 2d array representing the Latin square. Each row is converted to a permutation index, and that index is converted to a list of base 255 digits and replaced with an ASCII value. Each string is then joined using the ASCII character at 255.
Decompress, 45 bytes
Splits the input string at each ASCII value of 255, and parse each group as base 255 digits. Then using the number of groups, create a list of integers [0, length) and permute it according to each index and return it as a 2d array.
sumber
Python,
605245213556 bytescompress
takes the square as a multiline string, just like the examples and returns a binary string, whereasdecompress
does the opposite.Remove the last row+column and zip the rest.
base64
does not seem necessarysumber
Python 3, 1955 byte
Namun satu lagi yang menggunakan indeks permutasi ...
keluaran
sumber
Python3 -
3.5723.581 bytedataCompress
mengambil daftar tupel integer dan mengembalikan string.dateDeCompress
mengambil string dan mengembalikan daftar tupel integer.Singkatnya, untuk setiap baris, program ini mengambil indeks permutasi garis itu dan menyimpannya di basis 36. Dekompresi membutuhkan waktu lama dengan input besar tetapi kompresi sangat cepat bahkan pada input besar.
Pemakaian:
dataCompress([(2,0,1),(1,2,0),(0,1,2)])
hasil:
c|4|3|0
dataDeCompress("c|4|3|0")
hasil:
[(2, 0, 1), (1, 2, 0), (0, 1, 2)]
sumber
permutations
panggilan dalamlist
panggilan -permutations
mengembalikan generator, yang dengan malas menghasilkan semua permutasi, tetapi jika Anda mencoba membuatnya menjadilist
, itu dengan bersemangat menghasilkan semua permutasi, yang membutuhkan Waktu yang sangat lama.O(n)
waktu, daripada pendekatanO(n!)
brute force memeriksa semua permutasi .Java, 2310 byte
Kami mengonversi setiap baris kuadrat menjadi angka yang menunjukkan permutasi leksikografis yang menggunakan angka faktoradik, yang juga dikenal sebagai sistem bilangan faktorial , yang berguna untuk permutasi penomoran.
Kami menulis kuadrat ke file biner di mana byte pertama adalah ukuran kuadrat, dan kemudian setiap baris memiliki satu byte untuk jumlah byte dalam representasi biner dari Java BigInteger, diikuti oleh byte dari BigInteger itu.
Untuk membalikkan proses dan mendekompresi kuadrat kita membaca ukuran kembali dan kemudian setiap BigInteger, dan menggunakan nomor itu untuk menghasilkan setiap baris kuadrat.
Permutor diadaptasi dari kelas yang saya tulis beberapa tahun lalu untuk bekerja dengan permutasi:
Pemakaian:
Dengan kotak Latin
latin.txt
, kompres:Dan dekompreslah:
sumber