Perl 69 bytes
s;.;y/XVI60-9/CLXVIX/dfor$a[$_].="32e$&"%72726;gefor 1..100;print"@a"
Funciona a modo de fórmula mágica. La expresión "32e$&"%72726
transforma cada dígito de la siguiente manera:
0⇒32, 1⇒320, 2⇒3200, 3⇒32000, 4⇒29096, 5⇒56, 6⇒560, 7⇒5600, 8⇒56000, 9⇒50918
Después de aplicar la traducción y/016/IXV/
, tenemos esto en su lugar:
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
El resto de los dígitos ( 2-57-9
) se eliminan. Tenga en cuenta que esto podría mejorarse en un byte mediante el uso de una fórmula que se traduce en 012
lugar de 016
, simplificando /XVI60-9/
a /XVI0-9/
. No pude encontrar uno, pero quizás tengas mejor suerte.
Una vez que un dígito se ha transformado de esta manera, el proceso se repite para el siguiente dígito, agregando el resultado y traduciendo los XVI
s anteriores al CLX
mismo tiempo que ocurre la traducción para el nuevo dígito.
Actualización La
búsqueda exhaustiva no reveló nada más corto. Sin embargo, encontré una solución alternativa de 69 bytes:
s;.;y/XVI0-9/CLXIXV/dfor$a[$_].="57e$&"%474976;gefor 1..100;print"@a"
Este usa una 0-2
sustitución para IXV
, pero tiene un módulo que es un dígito más largo.
Actualización: 66 65 bytes
Esta versión es notablemente diferente, por lo que probablemente debería decir algunas palabras al respecto. ¡La fórmula que usa es en realidad un byte más!
Incapaz de acortar la fórmula más de lo que es, decidí jugar al golf con lo que tenía. No pasó mucho tiempo hasta que recordé a mi viejo amigo $\
. Cuando print
se emite una declaración, $\
se agrega automáticamente al final de la salida. Pude deshacerme de la $a[$_]
construcción incómoda para una mejora de dos bytes:
s;.;y/XVI60-9/CLXVIX/dfor$\.="32e$&"%72726;ge,$\=!print$"for 1..100
Mucho mejor, pero eso $\=!print$"
todavía se veía un poco detallado. Entonces recordé una fórmula alternativa de igual longitud que había encontrado que no contenía el número 3
en ninguna de sus transformaciones de dígitos. Por lo tanto, debería ser posible usar $\=2+print
en su lugar, y sustituir el resultado 3
con un espacio:
s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;ge,$\=2+print for 1..100
También 67 bytes, debido al espacio en blanco necesario entre print
y for
.
Editar : Esto se puede mejorar en un byte, moviendo print
al frente:
$\=2+print!s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;gefor 1..100
Debido a que la sustitución debe evaluarse completamente antes de la print
, la asignación a $\
ocurrirá en último lugar. Eliminar el espacio en blanco entre ge
y for
emitirá una advertencia de desaprobación, pero por lo demás es válido.
Pero, si hubiera una fórmula que no utilizara un 1
lugar, se $\=2+print
convierte $\=print
en otros dos bytes de ahorro. Incluso si fuera un byte más, aún sería una mejora.
Como resultado, dicha fórmula existe, pero es un byte más larga que la original, lo que resulta en una puntuación final de 65 bytes :
$\=print!s;.;y/XVI60-9/CLXXI V/dfor$\.="37e$&"%97366;gefor 1..100
Metodología
Se hizo la pregunta de cómo se puede encontrar una fórmula de este tipo. En general, encontrar una fórmula mágica para generalizar cualquier conjunto de datos es una cuestión de probabilidad. Es decir, desea elegir una forma que sea lo más probable posible para producir algo similar al resultado deseado.
Examing los primeros números romanos:
0:
1: I
2: II
3: III
4: IV
5: V
6: VI
7: VII
8: VIII
9: IX
Hay cierta regularidad para ser visto. Específicamente, de 0-3 y luego nuevamente de 5-8 , cada término sucesivo aumenta en longitud en un número. Si quisiéramos crear un mapeo de dígitos a números, querríamos tener una expresión que también aumente su longitud en un dígito por cada término sucesivo. Una opción lógica es k • 10 d donde d es el dígito correspondiente yk es cualquier constante entera.
Esto funciona para 0-3 , pero 4 necesita romper el patrón. Lo que podemos hacer aquí es tachuela en un módulo:
k • 10 d % m , donde m es un lugar entre k • 10 3 y k • 10 4 . Esto dejará el rango 0-3 intacto y modificará 4 de manera tal que no contendrá cuatro I
s. Si además restringimos nuestro algoritmo de búsqueda de modo que el residuo modular de 5 , llamémoslo j , sea menor que m / 1000 , esto asegurará que también tengamos regularidad de 5-8 . El resultado es algo como esto:
0: k
1: k0
2: k00
3: k000
4: ????
5: j
6: j0
7: j00
8: j000
9: ????
Como puede ver, si reemplazamos 0
con I
, ¡ 0-3 y 5-8 están garantizados para mapearse correctamente! Sin embargo, los valores para 4 y 9 deben ser forzados. Específicamente, 4 debe contener uno 0
y uno j
(en ese orden), y 9 debe contener uno 0
, seguido de otro dígito que no aparece en ningún otro lugar. Ciertamente, hay una serie de otras fórmulas, que por casualidad podrían producir el resultado deseado. Algunos de ellos incluso pueden ser más cortos. Pero no creo que haya ninguno que tenga tanto éxito como este.
También experimenté con múltiples reemplazos para I
y / o V
con algún éxito. Pero, por desgracia, nada más corto que lo que ya tenía. Aquí hay una lista de las soluciones más cortas que encontré (la cantidad de soluciones de 1-2 bytes más pesadas son demasiadas para enumerarlas):
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