Un carré latin est un carré qui n'a pas de symboles répétés dans les lignes ou colonnes: .
13420
21304
32041
04213
40132
Et comme de nombreux joueurs de Sudoku le savent, vous n'avez pas besoin de tous les nombres pour déduire les nombres restants.
Votre défi est de compresser un carré latin en aussi peu d'octets que possible. Vous devez fournir un ou deux programmes qui compressent / décompressent.
Infos diverses:
- Les nombres utilisés seront toujours
0..N-1
, oùN
est la longueur du bord du carré, etN<=25
- Lors de la décompression, le carré latin doit être identique à l'entrée.
- Votre programme (s) devrait être en mesure de (dé) compresser n'importe quel carré latin (dans la taille maximale du carré), pas seulement ceux que j'ai fournis. Les taux de compression devraient également être similaires.
- Vous devez réellement exécuter la compression et le décompresseur pour obtenir votre score (pas d'exécutions de fin d'univers)
Les cas de test peuvent être trouvés sur github . Votre score est la taille totale des cas de test compressés.
EDIT: À 20h07 le 7 juillet, j'ai mis à jour les cas de test (afin de résoudre un problème de génération). Veuillez réexécuter votre programme sur les nouveaux cas de test. Merci Anders Kaseorg .
code-challenge
compression
Nathan Merrill
la source
la source
0
cependantn-1
:)n
différents symboles. : PRéponses:
Python,
1281,3751268,625 octetsNous codons le carré latin une «décision» à la fois, où chaque décision prend l'une de ces trois formes:
À chaque étape, nous faisons toutes les inférences logiques que nous pouvons en fonction des décisions précédentes, puis sélectionnons la décision avec le plus petit nombre de choix possibles, qui prennent donc le plus petit nombre de bits à représenter.
Les choix sont fournis par un simple décodeur arithmétique (div / mod par le nombre de choix). Mais cela laisse une certaine redondance dans l'encodage: si k décode en un carré où le produit de tous les nombres de choix était m , alors k + m , k + 2⋅ m , k + 3⋅ m ,… décodent vers le même carré avec un état résiduel à la fin.
Nous profitons de cette redondance pour éviter d'encoder explicitement la taille du carré. Le décompresseur commence par essayer de décoder un carré de taille 1. À chaque fois que le décodeur termine avec l'état de restes, il jette ce résultat, soustrait m du nombre d'origine, augmente la taille de 1 et essaie à nouveau.
Sortie:
la source
np.stack()
. Dans ce cas, il peut être remplacé parnp.array([…])
, et je l'ai fait dans la version actuelle.MATLAB,
3'062.52'888.125 octetsCette approche abandonne simplement la dernière ligne et la dernière colonne du carré, et convertit chaque entrée en mots d'une certaine profondeur de bits. La profondeur de bits est choisie minimale pour le carré de taille donné. (Suggestion de @KarlNapf) Ces mots sont simplement ajoutés les uns aux autres. La décompression est juste l'inverse.
La somme de tous les cas de test est de 23'105 bits ou 2'888.125 octets. (Toujours valable pour les cas de test mis à jour, car la taille de mes sorties ne dépend que de la taille de l'entrée.)
la source
n=9..16
4 bits suffisent.Python 3, 10772 bits (1346,5 octets)
Prend 0,1 seconde pour compresser et décompresser les cas de test combinés.
Vérifiez le score sur Ideone .
la source
len(possible)
est 1 etpossible.index(rows[i][j])
est 0 , donc ce symbole est encodé sans frais.J , 2444 octets
S'appuie sur la fonction intégrée
A.
pour convertir vers et depuis une permutation d'entiers [0, n) et un indice de permutation.Compresser, 36 octets
L'entrée est un tableau 2D représentant le carré latin. Chaque ligne est convertie en un index de permutation, et cet index est converti en une liste de 255 chiffres de base et remplacé par une valeur ASCII. Chaque chaîne est ensuite jointe à l'aide du caractère ASCII à 255.
Décompresser, 45 octets
Fractionne la chaîne d'entrée à chaque valeur ASCII de 255 et analyse chaque groupe en tant que chiffres de base 255. Ensuite, en utilisant le nombre de groupes, créez une liste d'entiers [0, longueur) et permutez-la en fonction de chaque index et retournez-la sous la forme d'un tableau 2D.
la source
Python,
605245213556 octetscompress
prend le carré comme une chaîne multiligne, tout comme les exemples et renvoie une chaîne binaire, tandis quedecompress
fait le contraire.Retirez la dernière ligne + colonne et fermez le reste.
base64
ne semble pas nécessairela source
Python 3, 1955 octets
Encore un autre qui utilise des indices de permutation ...
sortie
la source
Python3 -
3 5723 581 octetsdataCompress
prend une liste de tuples entiers et retourne une chaîne.dateDeCompress
prend une chaîne et retourne une liste de tuples entiers.En bref, pour chaque ligne, ce programme prend cet indice de permutation de lignes et l'enregistre en base 36. La décompression prend beaucoup de temps avec de grandes entrées mais la compression est vraiment rapide même sur de grandes entrées.
Usage:
dataCompress([(2,0,1),(1,2,0),(0,1,2)])
résultat:
c|4|3|0
dataDeCompress("c|4|3|0")
résultat:
[(2, 0, 1), (1, 2, 0), (0, 1, 2)]
la source
permutations
appels dans leslist
appels -permutations
renvoie un générateur, qui génère paresseusement toutes les permutations, mais si vous essayez d'en faire unlist
, il génère avec impatience toutes les permutations, ce qui prend un très long temps.O(n)
temps, plutôt que l'O(n!)
approche par force brute de vérification de toutes les permutations .Java, 2310 octets
Nous convertissons chaque ligne du carré en un nombre représentant la permutation lexicographique qu'il utilise en utilisant des nombres factoriels, également connu sous le nom de système de nombres factoriels , qui est utile pour la numérotation des permutations.
Nous écrivons le carré dans un fichier binaire où le premier octet est la taille du carré, puis chaque ligne a un octet pour le nombre d'octets dans la représentation binaire d'un Java BigInteger, suivi des octets de ce BigInteger.
Pour inverser le processus et décompresser le carré, nous lisons la taille, puis chaque BigInteger, et utilisons ce nombre pour générer chaque ligne du carré.
Permutor est adapté d'une classe que j'ai écrite il y a quelques années pour travailler avec des permutations:
Usage:
Avec un carré latin
latin.txt
dedans, compressez-le:Et décompressez-le:
la source