Cordes de golf

22

J'ai toujours échoué à donner une réponse aux qui nécessitent une compression de chaîne, la principale raison étant que je ne sais pas utiliser les outils de compression de chaîne aussi efficacement que je le devrais .

Pour cette raison, j'ai posté cette question. Contrairement à mes autres questions sur les astuces, ce n'est pas spécifique à la langue, ce qui signifie que si vous pouvez penser à des astuces dans votre propre langue, vous pouvez les publier (à condition de spécifier la langue). Des conseils généraux sont également appréciés.

Alors, comment puis-je utiliser les outils de compression de chaînes à leur efficacité maximale?

Beta Decay
la source

Réponses:

9

Conversion de base (CJam)

Un moyen facile de coder des chaînes ASCII qui ne commencent pas par un octet nul est de convertir la base 128 en entier, puis en base 256:

128b256b:c              e# Prints encoded string.
128b256b:c`"256b128b:c" e# Prints encoded string with decoder.

Cela utilise 7 bits pour coder chaque caractère ASCII.

Si la chaîne d'origine se compose uniquement, par exemple, de lettres minuscules et ne commence pas par un a , nous pouvons commencer par mapper "a...z"sur [0 ... 25], puis procéder comme ci-dessus:

'afm26b256b:c               e# Prints encoded string.
'afm26b256b:c`"256b26b'af+" e# Prints encoded string with decoder.

Enfin, si la chaîne d'origine ne comporte que quelques caractères uniques (communs dans l'art ASCII), il est généralement préférable de spécifier explicitement l'alphabet.

Par exemple:

" +-/\|"f#6b256b:c                       e# Prints encoded string.
" +-/\|"f#6b256b:c`"256b6b"" +-/\|"`"f=" e# Prints encoded string with decoder.

En règle générale, vous souhaitez que le premier caractère de la chaîne d'origine soit le deuxième caractère de l'alphabet, le caractère distinct suivant de la chaîne d'origine soit le premier caractère de l'alphabet, le caractère distinct suivant de la chaîne d'origine à être le troisième caractère de l'alphabet, le caractère distinct suivant de la chaîne d'origine pour être le quatrième caractère de l'alphabet, etc.

L'encodeur du dernier exemple fonctionne comme suit:

" +-/\|"f# e# Replace each character by its index in that string.
6b256b     e# Convert from base 6 (length of the alphabet) to base 256.
:c         e# Cast each digit to character.

Le décodeur du dernier exemple fonctionne comme suit:

256b6b     e# Convert from base 256 to base 6.
" +-/\|"f= e# Replace each digit by the corresponding character of the alphabet.
Dennis
la source
2
Je serais plus précis: en règle générale, vous voulez que le premier caractère de la chaîne d'origine soit le deuxième caractère de l'alphabet, le prochain caractère distinct de la chaîne d'origine soit le premier caractère de l'alphabet, ...
Peter Taylor
@PeterTaylor Added. Merci!
Dennis
9

Les questions de complexité plus grandes de Kolmogorov avec une certaine structure mais aucune formule simple (par exemple les paroles des chansons) ne bénéficieront généralement d'une approche basée sur la grammaire. En substance, vous extrayez des sous-chaînes répétées et les codez d'une manière ou d'une autre. C'est ce que fait Lempel-Ziv, en utilisant une classe de grammaires assez restreinte; si vous utilisez des grammaires plus générales, vous devez trouver comment coder les règles. Par exemple, une approche ici est le "codage de décalage", où vous décalez chaque octet source par le nombre de règles ( n), attribuez des octets 1aux nrègles, utilisez l' 0octet pour séparer les règles et remplacez à plusieurs reprises l'octet ipar la règle évaluée i. Enfin, vous annulez le décalage en soustrayant nde chaque octet.

J'ai en fait écrit un programme Java qui implémente différentes approches:

La plupart des approches suivent un processus en deux phases. Dans la première phase, la chaîne est convertie en une grammaire qui la génère; dans la deuxième phase, la grammaire est convertie en un programme GolfScript. Les implémentations de la première phase sont largement basées sur Charikar, Lehman, Liu, Panigrahy, Prabhakaran, Sahai et Shelat (2005) The smallest grammar problem , Information Theory, IEEE Transactions on, 51 (7), 2554-2576.

Il comprend également une approche Lempel-Ziv, une approche de codage de base et une approche de codage de longueur d'exécution, et identifie celle qui donne le programme le plus court.

Peter Taylor
la source
0

Stax

Dans le langage de golf du code Stax , il existe un petit outil utile appelé le compresseur littéral de cordes . Je ne sais pas comment cela fonctionne exactement, mais il y a une autre où je ne sais comment cela fonctionne. Il convertit les chaînes en nombres, puis en Base 256. C'est CP437 , avec 0x00 et 0xFF convertis pour la copie. C'est PackedStax. Vous pouvez convertir vos cordes avec le compresseur littéral de cordes puis l'emballer, pour une bonne compression.

En utilisant ce processus, la chaîne "Cette chaîne fait trente-deux octets" peut être convertie en v * "A] - | W4]} 3"% (la chaîne compressée est généralement entourée de guillemets pour faire la différence entre une chaîne normale dans Stax ) et enfin à üvìë! [┴╩qJu ← ▓α pour une compression / réduction de 18 octets, plus de la moitié.

Ethan Slota
la source