Perl 69 octets
s;.;y/XVI60-9/CLXVIX/dfor$a[$_].="32e$&"%72726;gefor 1..100;print"@a"
Fonctionne par formule magique. L'expression "32e$&"%72726
transforme chaque chiffre de la manière suivante:
0⇒32, 1⇒320, 2⇒3200, 3⇒32000, 4⇒29096, 5⇒56, 6⇒560, 7⇒5600, 8⇒56000, 9⇒50918
Après avoir appliqué la traduction y/016/IXV/
, nous avons ceci à la place:
0⇒32, 1⇒32 I , 2⇒32 II , 3⇒32 III , 4⇒29 I 9 V , 5⇒5 V , 6⇒5 VI , 7⇒5 VII , 8⇒5 VIII , 9⇒5 I 9 X 8
Les autres chiffres ( 2-57-9
) sont supprimés. On notera que ce pourrait être améliorée par un octet en utilisant une formule qui se traduit à la 012
place de 016
, ce qui simplifie /XVI60-9/
à /XVI0-9/
. Je n'ai pas pu en trouver, mais peut-être aurez-vous plus de chance.
Une fois qu'un chiffre a été transformé de cette manière, le processus se répète pour le chiffre suivant, en ajoutant le résultat et en traduisant les XVI
s précédents CLX
en même temps que la traduction du nouveau chiffre se produit.
La
recherche exhaustive n'a rien révélé de plus court. J'ai cependant trouvé une solution alternative à 69 octets:
s;.;y/XVI0-9/CLXIXV/dfor$a[$_].="57e$&"%474976;gefor 1..100;print"@a"
Celui-ci utilise une 0-2
substitution pour IXV
, mais a un modulo d'un chiffre de plus.
Mise à jour: 66 65 octets
Cette version est notablement différente, donc je devrais probablement en dire quelques mots. La formule qu'il utilise est en fait un octet de plus!
Incapable de raccourcir la formule plus qu'elle ne l'est, j'ai décidé de jouer avec ce que j'avais. Il ne fallut pas longtemps pour que je me souvienne de mon vieil ami $\
. Lorsqu'un print
état est émis, $\
est automatiquement ajouté à la fin de la sortie. J'ai pu me débarrasser de la $a[$_]
construction maladroite pour une amélioration de deux octets:
s;.;y/XVI60-9/CLXVIX/dfor$\.="32e$&"%72726;ge,$\=!print$"for 1..100
Beaucoup mieux, mais cela $\=!print$"
semblait encore un peu bavard. Je me suis alors souvenu d'une formule alternative de longueur égale que j'avais trouvée qui ne contenait le nombre 3
dans aucune de ses transformations de chiffres. Donc, il devrait être possible d'utiliser à la $\=2+print
place et de remplacer le résultat 3
par un espace:
s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;ge,$\=2+print for 1..100
Également 67 octets, en raison de l'espace nécessaire entre print
et for
.
Edit : Cela peut être amélioré d'un octet, en déplaçant le print
vers l'avant:
$\=2+print!s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;gefor 1..100
Étant donné que la substitution doit être évaluée complètement avant le print
, l'affectation à $\
aura toujours lieu en dernier. La suppression de l'espace entre ge
et for
émettra un avertissement de dépréciation, mais est par ailleurs valide.
Mais, s'il y avait une formule qui n'utilisait pas 1
n'importe où, $\=2+print
devient $\=print
pour deux octets supplémentaires d'économies. Même si c'était un octet de plus, ce serait quand même une amélioration.
En fait, une telle formule existe, mais elle est un octet de plus que l'original, ce qui donne un score final de 65 octets :
$\=print!s;.;y/XVI60-9/CLXXI V/dfor$\.="37e$&"%97366;gefor 1..100
Méthodologie
La question a été posée de savoir comment procéder pour trouver une telle formule. En général, trouver une formule magique pour généraliser n'importe quel ensemble de données est une question de probabilité. C'est-à-dire que vous voulez choisir une forme qui est aussi susceptible que possible de produire quelque chose de similaire au résultat souhaité.
Examen des premiers chiffres romains:
0:
1: I
2: II
3: III
4: IV
5: V
6: VI
7: VII
8: VIII
9: IX
il y a une certaine régularité à voir. Plus précisément, de 0 à 3 puis de 5 à 8 , chaque terme successif augmente de longueur d'un chiffre. Si nous voulions créer un mappage de chiffres à chiffres, nous voudrions avoir une expression qui augmente également en longueur d'un chiffre pour chaque terme successif. Un choix logique est k • 10 d où d est le chiffre correspondant et k est une constante entière.
Cela fonctionne pour 0-3 , mais 4 doit briser le modèle. Ce que nous pouvons faire ici, c'est coller sur un modulo:
k • 10 d % m , où m est quelque part entre k • 10 3 et k • 10 4 . Cela laissera la plage 0-3 intacte et modifiera 4 de sorte qu'elle ne contiendra pas quatre I
s. Si nous contraignons en outre notre algorithme de recherche de sorte que le résidu modulaire de 5 , appelons-le j , soit inférieur à m / 1000 , cela garantira que nous avons également une régularité de 5-8 . Le résultat est quelque chose comme ceci:
0: k
1: k0
2: k00
3: k000
4: ????
5: j
6: j0
7: j00
8: j000
9: ????
Comme vous pouvez le voir, si nous remplaçons 0
par I
, 0-3 et 5-8 sont tous garantis pour être correctement cartographiés! Les valeurs de 4 et 9 doivent cependant être forcées brutalement. Plus précisément, 4 doit contenir un 0
et un j
(dans cet ordre) et 9 doit en contenir un 0
, suivi d'un autre chiffre qui n'apparaît nulle part ailleurs. Certes, il existe un certain nombre d'autres formules qui, par un coup de hasard, pourraient produire le résultat souhaité. Certains d'entre eux peuvent même être plus courts. Mais je ne pense pas qu'il y en ait qui soient aussi susceptibles de réussir que celui-ci.
J'ai également expérimenté plusieurs remplacements pour I
et / ou V
avec un certain succès. Mais hélas, rien de plus court que ce que j'avais déjà. Voici une liste des solutions les plus courtes que j'ai trouvées (le nombre de solutions de 1 à 2 octets de plus est trop important pour être répertorié):
y/XVI60-9/CLXVIX/dfor$\.="32e$&"%72726
y/XVI0-9/CLXIXV/dfor$\.="57e$&"%474976
y/XVI0-9/CLXIVXI/dfor$\.="49e$&"%87971
y/XVI0-9/CLXIIXIV/dfor$\.="7e$&"%10606 #
y/XVI0-9/CLXIIXIV/dfor$\.="7e$&"%15909 # These are all essentially the same
y/XVI0-9/CLXIIXIV/dfor$\.="7e$&"%31818 #
y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535 # Doesn't contain 3 anywhere
y/XVI60-9/CLXXI V/dfor$\.="37e$&"%97366 # Doesn't contain 1 anywhere