Perl 69 octets
s;.;y/XVI60-9/CLXVIX/dfor$a[$_].="32e$&"%72726;gefor 1..100;print"@a"
Fonctionne par formule magique. L'expression "32e$&"%72726transforme 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 012place 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 XVIs précédents CLXen 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-2substitution 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 3dans aucune de ses transformations de chiffres. Donc, il devrait être possible d'utiliser à la $\=2+printplace et de remplacer le résultat 3par 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 printet for.
Edit : Cela peut être amélioré d'un octet, en déplaçant le printvers 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 geet forémettra un avertissement de dépréciation, mais est par ailleurs valide.
Mais, s'il y avait une formule qui n'utilisait pas 1n'importe où, $\=2+printdevient $\=printpour 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 Is. 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 0par 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 0et 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 Iet / ou Vavec 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