Votre mission aujourd'hui est d'inventer un compresseur de texte.
Tâche
Vous écrirez deux fonctions:
Le packer est une fonction qui accepte une chaîne de caractères ASCII (U + 0000 à U + 007F) et génère une chaîne Unicode (U + 0000 à U + 10FFFF), contenant le moins de caractères possible.
Le décompresseur est une fonction qui accepte une chaîne Unicode codée et génère exactement la chaîne ASCII d'origine.
Contribution
La seule entrée autorisée est la chaîne ASCII (pour le conditionneur) et la chaîne Unicode compressée (pour le décompresseur). Aucune entrée utilisateur, aucune connexion Internet, aucune utilisation du système de fichiers.
Vos fonctions peuvent avoir accès à cette liste de mots anglais . Vous pouvez utiliser cette liste en tant que fichier txt local ou copier son contenu dans votre code source sous la forme d'une chaîne ou d' un tableau de chaînes .
Vous ne pouvez pas coder en dur les extraits ci-dessous dans vos fonctions.
Sortie
La seule sortie autorisée pour les deux fonctions est une chaîne.
La sortie du décompresseur doit contenir exactement les mêmes caractères que l'entrée du packer.
Vos entrées et sorties peuvent utiliser n'importe quel encodage de caractères prenant en charge tous les Unicode (UTF-8/16/32, GB18030, ...), car votre score ne dépendra que du nombre de caractères Unicode dans la sortie. Veuillez préciser l'encodage que vous utilisez, cependant.
Pour compter le nombre de caractères Unicode dans votre sortie, vous pouvez utiliser cet outil: http://mothereff.in/byte-counter
Notation
Votre entrée doit pouvoir emballer et décompresser les 10 extraits de texte suivants (que j'ai pris sur ce forum).
Votre score sera la somme des tailles de vos 10 chaînes compressées (en caractères Unicode) + la taille de vos deux fonctions (en caractères Unicode aussi)
Ne comptez pas la taille du dictionnaire si vous l'utilisez.
Veuillez inclure dans vos entrées le "score" de chaque extrait et leur version compactée.
Le score le plus bas l'emporte.
Les données
Voici les extraits à encoder pour calculer votre score:
1: paroles de Rick Roll (1870b): Nous ne sommes pas étrangers au code du golf, vous connaissez les règles, et moi aussi
Nous ne sommes pas des étrangers à aimer Vous connaissez les règles et moi aussi Un engagement total à quoi je pense Vous n'obtiendrez cela d'aucun autre gars Je veux juste te dire comment je me sens Je dois te faire comprendre Je ne t'abandonnerai jamais Je ne te laisserai jamais tomber Je ne vais jamais courir et te déserter Je ne te ferai jamais pleurer Je ne te dirai jamais au revoir Je ne vais jamais mentir et te blesser Nous nous connaissons depuis si longtemps Votre cœur a mal mais Tu es trop timide pour le dire À l'intérieur, nous savons tous les deux ce qui se passe Nous connaissons le jeu et nous allons y jouer Et si tu me demandes comment je me sens Ne me dis pas que tu es trop aveugle pour voir Je ne t'abandonnerai jamais Je ne te laisserai jamais tomber Je ne vais jamais courir et te déserter Je ne te ferai jamais pleurer Je ne te dirai jamais au revoir Je ne vais jamais mentir et te blesser Je ne t'abandonnerai jamais Je ne te laisserai jamais tomber Je ne vais jamais courir et te déserter Je ne te ferai jamais pleurer Je ne te dirai jamais au revoir Je ne vais jamais mentir et te blesser (Ooh, abandonne-toi) (Ooh, abandonne-toi) (Ooh) Je ne donnerai jamais, je ne donnerai jamais (T'abandonner) (Ooh) Je ne donnerai jamais, je ne donnerai jamais (T'abandonner) Nous nous connaissons depuis si longtemps Votre cœur a mal mais Tu es trop timide pour le dire À l'intérieur, nous savons tous les deux ce qui se passe Nous connaissons le jeu et nous allons y jouer Je veux juste te dire comment je me sens Je dois te faire comprendre Je ne t'abandonnerai jamais Je ne te laisserai jamais tomber Je ne vais jamais courir et te déserter Je ne te ferai jamais pleurer Je ne te dirai jamais au revoir Je ne vais jamais mentir et te blesser Je ne t'abandonnerai jamais Je ne te laisserai jamais tomber Je ne vais jamais courir et te déserter Je ne te ferai jamais pleurer Je ne te dirai jamais au revoir Je ne vais jamais mentir et te blesser Je ne t'abandonnerai jamais Je ne te laisserai jamais tomber Je ne vais jamais courir et te déserter Je ne te ferai jamais pleurer Je ne te dirai jamais au revoir Je ne vais jamais mentir et te blesser
2: Le golfeur (412b): Golf ASCII-art
'\. . |> 18 >> \. '. | O >>. «o | \. | / \. | / /. » | jgs ^^^^^^^ `^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^
3: le diamant numéro (233b): Imprimez ce diamant
1 121 12321 1234321 123454321 12345654321 1234567654321 123456787654321 12345678987654321 123456787654321 1234567654321 12345654321 123454321 1234321 12321 121 1
4: l'alphabet quatre fois (107b): imprimer l'alphabet quatre fois
abcdefghijklmnopqrstuvwxyz qwertyuiopasdfghjklzxcvbnm pyfgcrlaoeuidhtnsqjkxbmwvz zyxwvutsrqponmlkjihgfedcba
5: Paroles d'Old McDonald's (203b): Fonction Old MacDonald
Old MacDonald avait une ferme, EIEIO, Et sur cette ferme, il avait une vache, EIEIO, Avec un moo moo ici et un moo moo là, Ici un moo, là un moo, partout un moo moo, Le vieux MacDonald avait une ferme, EIEIO!
6: Paroles de chanson Rock around the clock (144b): Rock Around the Clock
1, 2, 3 heures, 4 heures rock, 5, 6, 7 heures, 8 heures rock, 9, 10, 11 heures, 12 heures rock, On va basculer 24 heures sur 24 ce soir.
7: Hello World (296b): Dites "Bonjour" au monde dans l'art ASCII
_ _ _ _ _ _ _ | | | | ___ | | | ___ __ _____ _ __ | | __ | | | | | _ | | / _ \ | | / _ \ \ \ / \ / / _ \ | «__ | | / _` | | | _ | __ / | | (_) | \ VV / (_) | | | | (_ | | _ | | _ | | _ | \ ___ | _ | _ | \ ___ () \ _ / \ _ / \ ___ / | _ | | _ | \ __, _ (_) | /
8: bénédiction irlandaise (210b): une vieille bénédiction irlandaise
Que la route monte pour te rencontrer Que le vent soit toujours dans ton dos Que le soleil brille chaud sur votre visage Les pluies tombent doucement sur vos champs Et jusqu'à ce que nous nous revoyions Que Dieu vous tienne au creux de sa main
9: Il y avait une vieille dame (1208b): Il y avait une vieille dame
Il y avait une vieille dame qui a avalé une mouche. Je ne sais pas pourquoi elle a avalé cette mouche, Peut-être qu'elle mourra. Il y avait une vieille dame qui a avalé une araignée, Cela se tortillait, se tortillait et se tortillait en elle. Elle a avalé l'araignée pour attraper la mouche, Je ne sais pas pourquoi elle a avalé cette mouche, Peut-être qu'elle mourra. Il y avait une vieille dame qui a avalé un oiseau, Quelle absurdité d'avaler un oiseau. Elle a avalé l'oiseau pour attraper l'araignée, Elle a avalé l'araignée pour attraper la mouche, Je ne sais pas pourquoi elle a avalé cette mouche, Peut-être qu'elle mourra. Il y avait une vieille dame qui a avalé un chat, Imaginez cela pour avaler un chat. Elle a avalé le chat pour attraper l'oiseau, Elle a avalé l'oiseau pour attraper l'araignée, Elle a avalé l'araignée pour attraper la mouche, Je ne sais pas pourquoi elle a avalé cette mouche, Peut-être qu'elle mourra. Il y avait une vieille dame qui a avalé un chien, Quel porc pour avaler un chien. Elle a avalé le chien pour attraper le chat, Elle a avalé le chat pour attraper l'oiseau, Elle a avalé l'oiseau pour attraper l'araignée, Elle a avalé l'araignée pour attraper la mouche, Je ne sais pas pourquoi elle a avalé cette mouche, Peut-être qu'elle mourra. Il y avait une vieille dame qui a avalé un cheval, Elle est morte bien sûr.
10: adresse de Gettysburg (1452b): quelle est l'adresse aléatoire de Gettysburg
Il y a quatre ans et sept ans, nos pères ont fait naître sur ce continent une nouvelle nation, conçue dans la liberté et dédiée à la proposition que tous les hommes sont créés égaux. Nous sommes maintenant engagés dans une grande guerre civile, testant si cette nation, ou toute nation ainsi conçue et si dévouée, peut durer longtemps. Nous sommes rencontrés sur un grand champ de bataille de cette guerre. Nous en sommes venus à consacrer une partie de ce domaine, comme lieu de repos final pour ceux qui ici ont donné leur vie pour que cette nation puisse vivre. Il est tout à fait approprié et approprié que nous le fassions. Mais, dans un sens plus large, nous ne pouvons pas dédier, nous ne pouvons pas consacrer, nous ne pouvons pas sanctifier ce terrain. Les braves, vivants et morts, qui ont lutté ici, l'ont consacré, bien au-dessus de notre pauvre pouvoir d'ajouter ou de nuire. Le monde ne remarquera pas, ni ne se souviendra longtemps de ce que nous disons ici, mais il ne peut jamais oublier ce qu'ils ont fait ici. Il nous appartient plutôt aux vivants de se consacrer ici à l'œuvre inachevée qu'ils ont jusqu'ici si noblement avancé. C'est plutôt pour nous d'être ici dédiés à la grande tâche qui nous attend - que de ces morts honorés nous consacrons une plus grande dévotion à cette cause pour laquelle ils ont donné la dernière pleine mesure de dévotion - que nous résolvons ici fortement que ces morts ne sont morts en vain - que cette nation, sous Dieu, aura une nouvelle naissance de liberté - et que le gouvernement du peuple, par le peuple, pour le peuple, ne périsse pas de la terre.
Total (non compressé): 6135 caractères / octets.
S'amuser!
private static final String RICK_ROLL_RETURN = "We're no strangers to love...
Réponses:
Haskell - 5322 points
Octets de code:
686
Format original :
6147
= 1871+415+234+108+204+145+297+211+1209+1453
Taille codée:
4636
= 1396+233+163+92+153+115+197+164+979+1144
But :
686+ 4636
Compression du nombre de caractères:
~25%
Code
Mis à part les optimisations, cela stocke les valeurs entre
0
et7f
en caractères unicode comme facteurs premiers.Il ne réduit pas le nombre d'octets de la sortie codée, il ne fait que diminuer le nombre de caractères unicode. Par exemple, le test n ° 4 contient des
108
caractères et la sortie encodée,92
. Leurs tailles respectives sont cependant108
et en364
octets.Comment ça marche
Codage
n
.n
est ensuite converti en une liste de ses facteurs premiers,ps
.1
. Cela signifie qu'ils, les facteurs, peuvent être stockés sous forme d'index sur aussi peu que 5 bits.1
est un cas particulier et est représenté par une liste vide.ps
l'encodage peut maintenant commencer.ps
est converti en son index dans la liste de 32 facteurs uniques (dans le code ci-dessus, cette liste est identifiée commea
).ps
faut l'aplatir. Pour préserver l'intégrité des données, chaque liste est convertie en une autre liste de deux partiesfs
.fs
peuvent ensuite être regroupés en caractères unicode en utilisant le décalage de bits.Décodage
1
s’inscrit, je voudrais vous le rappelerproduct [] == 1
.Les tests
L'utilisation de cette interface pour les tests serait pénible, j'ai donc utilisé cette fonction pour fournir les résultats ci-dessous.
Échantillon
La sortie de la fonction d'encodage
g
pour le test # 4 est ceci"\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"
ou si vous êtes un adepte du charabia, ceci
𘑥𡁢𑒁豱𐲂숼𨐢𘑥𐦅𒁃𰠱𑃥踾𑃱𐲂𓂡𠐣𘰢숼𨐢𐡁衣쑡𡁡𘑇𑑡𒂡衂𐲄숼𨐡𡈽𑃢쑁豁𑃢쑢ꡃ𐦃貱𐡑𘡤𠐡裱𘱢𑑡𡈹
Notes supplémentaires
edTest
la taille des tests sont tous cohérents mais diffèrent toujours de la taille indiquée dans la question.—
) que j'ai remplacés-
car ils sont en dehors de la plage0
-7f
.00
le cas de base,01
tout10
répéter , répéter sauf le dernier,11
répéter sauf les deux derniers.la source
abcdefghijklm...
à𘑥𡁢𑒁豱...
, pourriez - vous expliquer un peu plus s'il vous plaît? De plus, j'ai corrigé le nombre de caractères et converti les em-tirets dans # 10, dans la question. Cependant, mon nombre d'ombles est toujours différent du vôtre. Je ne sais pas pourquoi, j'ai utilisé l'outil mothereff.in.C ++ (C ++ 11), 2741 points
Cette réponse utilise UTF-32 comme codage pour le texte compressé.
Le nombre de caractères et le score
Code: 593 caractères (la nouvelle ligne de fin est supprimée)
Textes compressés (caractères Unicode) : 654 + 145 + 82 + 38 + 51 + 104 + 73 + 423 + 506 = 2148 (compté avec
wc -m
pour le nombre de caractères Unicode plutôt que d'octets, le nombre d'octets est, comme avec la réponse de @ gxtaillon , supérieur aux originaux, 8413 octets au total, comme compté avecwc -c
).Taux de compression (ASCII à unicode) : 35,01% (en utilisant les 6 135 octets de la question (les mêmes que
wc -c
))Il faut se méfier:
De nombreux shells ne peuvent pas gérer les caractères unicode produits par ce programme. Ainsi, la décompression peut entraîner la coupure du texte quelque part lorsque le shell ne peut pas gérer un caractère, car la saisie est effectuée via
stdin
le shell.Compilation
Il devrait compiler avec
clang++
etg++ -std=c++11
, mais il affichera quelques avertissements sur la priorité des opérateurs, car une expression commeb<<20-n&0xFFFFF
ne sera pas traitée comme((b << 20) - n) & 0xFFFFF
, comme on pourrait s'y attendre, mais plutôt comme(b << (20 - n)) & 0xFFFFF
.Usage
./compress
../compress c
pour compresser ou./compress d
décompresser. (Attention, laisser de côté l'option donne un SEGFAULT (la vérification des erreurs coûte tellement cher ...) et d'autres options (comme utiliser à laD
place ded
) peuvent donner des résultats inattendusstdin
et la sortie est écrite dansstdout
Comment ça marche
Non golfé
Explication
Comme tous les caractères unicode de
U+0000
àU+10FFFF
sont autorisés, nous pouvons utiliser 20 bits par caractère unicode:U+FFFFF
utilise 20 bits et est toujours inclus dans la plage autorisée. Ainsi, nous essayons simplement de mettre tous les bits de caractère ASCII individuels dans les caractères unicode pour stocker plusieurs caractères ASCII dans un caractère unicode. Cependant, nous devons également stocker le nombre de bits utilisés dans le dernier caractère unicode, car les bits inutiles non utilisés peuvent être interprétés comme des caractères ASCII compressés appropriés. Comme le nombre maximum de bits utilisés dans le dernier caractère unicode est de 20, nous aurons besoin de 5 bits pour cela, qui sont placés au début des données compressées.Exemple de sortie
Ceci est la sortie de l'exemple # 4 (tel que donné par
less
):(
쏏𦛏
donnez des<U+C3CF><U+266CF>
codes de caractères, mais je me suis peut-être trompé)la source
Python 3, 289 + 818 = 1107 points
Seulement légèrement joué au golf.
La taille totale du code est de 289 octets et code les 6 135 octets donnés en 818 caractères Unicode - le nombre total d'octets de sortie est de 3 201 octets, nettement plus petit que les entrées d'origine.
Encode en utilisant zlib, puis secondairement en utilisant l'encodage unicode. Une logique supplémentaire était nécessaire pour éviter les substituts (que Python déteste vraiment).
Exemple de sortie de # 4, vu par
less
(37 caractères Unicode):Programme pilote pour les tests:
Nombre d'octets de sortie:
la source
p
est le packer,u
est le déballeur.Python 2 - 1141 points
La taille du code est en
281
octets et il code les6135
octets en860
caractères unicode.Comment ça marche:
Pour encoder:
19
bits, ajoutez un1
peu au début de chacun d'eux, puis convertissez-les en caractères Unicode.Le décodage est l'inverse.
Notez que certaines versions de python ne peuvent gérer que des caractères unicode jusqu'à
0xFFFF
, et donc ce code soulèvera unValueError
.la source