Japt , 43 octets
"Ýûÿ©ÿßY÷ß"®c s4äëAU ¬£2839¤ë4X÷d0S1U
Contient certains non imprimables. Essayez-le en ligne!
Correspondances: 13 octets de données compressées, 9 octets pour les décompresser et 21 octets pour former la sortie.
Explication
Code non golfé:
"Ýûÿ©ÿßY÷ß"® c s4à ¤ ëAU ¬ £ 2839¤ ë4Xà · d0S1U
"Ýûÿ©ÿßY÷ß"mZ{Zc s4} s2 ëAU q mX{2839s2 ë4X} qR d0S1U
Il y a exactement 4 possibilités de lignes différentes: ( #
représente un chiffre)
#
#
# #
###
Ainsi, chaque numéro peut être stocké sous la forme d'un ensemble de cinq chiffres de base 4. Étant donné que chaque numéro peut ensuite être stocké sur 10 bits, le total est de 100 bits, ce qui correspond à 13 octets. Je vais sauter le processus de compression et expliquer à la place la décompression.
mZ{Zc s4}
mZ{ } // Replace each character Z in the compressed string with the following:
Zc // Take the char-code of Z.
s4 // Convert to a base-4 string.
Après la décompression, la chaîne compressée de 13 octets ressemble à ceci:
3131332333332111200122213333313321011121213133133133
Notez que cela échouerait si l'une des exécutions à 4 chiffres commençait par 0
, car les zéros de tête seraient laissés de côté lors de l' s4
exécution. Nous pouvons résoudre ce problème en ayant 0
represent #
, qui n'apparaît que trois fois, et aucun de ceux-ci ne tombe au début d'une exécution à 4 chiffres.
s2 // Slice off the first two chars of the result.
D'accord, donc pour que notre chaîne de 50 chiffres se comprime bien en morceaux de 4, nous avons dû ajouter deux chiffres supplémentaires. Les ajouter au début de la chaîne signifie que nous pouvons les couper avec un octet ¤
.
ëAU // Take every 10th (A) char in this string, starting at index <input> (U).
De manière embarrassante, Japt n'a pas de fonction intégrée pour diviser une chaîne en tranches de longueur X. Cependant, il a une fonction intégrée pour obtenir chaque Xème caractère, afin que nous puissions stocker toutes les données en codant d'abord toutes les lignes supérieures, puis toutes les deuxièmes rangées, etc.
Nous avons donc maintenant la chaîne à 5 chiffres codant le chiffre que nous voulons créer, par exemple 32223
pour 0
.
q mX{2839s2 ë4X} qR
q // Split the resulting string into chars.
mX{ } // Replace each char X with the result of this function:
2839s2 // Convert the magic number 2839 to a binary string.
ë4X // Take every 4th char of this string, starting at index X.
qR // Join the result with newlines.
Pour expliquer le nombre magique, reportez-vous aux quatre lignes distinctes. Si vous remplacez #
par 1
et
par 0
, vous obtenez
100
001
101
111
Transposer cela et ensuite se joindre à une seule chaîne nous donne 101100010111
. Convertissez en décimal et, voilà, vous avez 2839. Inverser le processus mappe les chiffres0123
dans les quatre lignes binaires indiquées ci-dessus.
Presque fini! Il ne reste plus qu'à ajouter les espaces et les chiffres:
d0S1U // In the resulting string, replace 0 with " " (S) and 1 with <input> (U).
Et hop, la sortie implicite s'occupe du reste. Je suis désolé que cette explication soit si longue, mais je ne vois aucun moyen réel de la jouer au golf sans la rendre moins compréhensible (si elle est compréhensible ...)