Escriba un programa que cuente del 1 al 100 en números romanos e imprima estos números por salida estándar. Cada uno de los números debe estar separado por espacios.
No puede utilizar ninguna función integrada para transformar a números romanos ni una aplicación externa o biblioteca para hacerlo.
El resultado deseado es
I II III IV V VI VII VIII IX X XI XII XIII XIV XV XVI XVII XVIII XIX XX XXI XXII XXIII XXIV XXV XXVI XXVII XXVIII XXIX XXX XXXI XXXII XXXIII XXXIV XXXV XXXVI XXXVII XXXVIII XXXIX XL XLI XLII XLIII XLIV XLV XLVI XLVII XLVIII XLIX L LI LII LIII LIV LV LVI LVII LVIII LIX LX LXI LXII LXIII LXIV LXV LXVI LXVII LXVIII LXIX LXX LXXI LXXII LXXIII LXXIV LXXV LXXVI LXXVII LXXVIII LXXIX LXXX LXXXI LXXXII LXXXIII LXXXIV LXXXV LXXXVI LXXXVII LXXXVIII LXXXIX XC XCI XCII XCIII XCIV XCV XCVI XCVII XCVIII XCIX C
Como es un desafío de código de golf, gana el código más corto .

Respuestas:
Perl 69 bytes
Funciona a modo de fórmula mágica. La expresión
"32e$&"%72726transforma 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 en012lugar de016, 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
XVIs anteriores alCLXmismo 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:
Este usa una
0-2sustitución paraIXV, pero tiene un módulo que es un dígito más largo.Actualización:
6665 bytesEsta 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
$\. Cuandoprintse 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: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úmero3en ninguna de sus transformaciones de dígitos. Por lo tanto, debería ser posible usar$\=2+printen su lugar, y sustituir el resultado3con un espacio:También 67 bytes, debido al espacio en blanco necesario entre
printyfor.Pero, si hubiera una fórmula que no utilizara un
1lugar, se$\=2+printconvierte$\=printen 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 :
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:
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
Is. 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:Como puede ver, si reemplazamos
0conI, ¡ 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 uno0y unoj(en ese orden), y 9 debe contener uno0, 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
Iy / oVcon 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):fuente
HTML + JavaScript + CSS (137)
HTML (9)
JavaScript (101)
CSS (27)
Salida
...
Demo en JSBin
fuente
document.write('<ol>'+"<li style='list-style:upper-roman'/>".repeat(100)+'</ol>')(ES6)document.write("<li style='list-style:upper-roman'/>".repeat(100))Python 116
mejor código de golf de la respuesta de Scleaver:
fuente
Pitón, 139
fuente
C,
177160147 caracteresHay soluciones más cortas, pero ninguna en C, así que aquí está mi intento.
Nueva solución, completamente diferente de la anterior:
Solución anterior (160 caracteres):
Lógica:
1.
fimprime un número del 1 al 10.cson los dígitos utilizados, que pueden serIVXoXLC. Llamado una vez por las decenas una vez por las.2. If
n%5==0: no imprime nada oc[n/5]cuál esIoV(oLoC).3. Si
n%4==4-4o9- imprimeI(oX), porn+1.4. If
n>4- imprimir5(es decir,VoL) entoncesn-5.5. If
n<4- imprimeIentoncesn-1(es decir,nvecesI).fuente
f(c,n){printf("%.*s",n%5>3?2:n%5+n/5,"XLXXXCIVIIIX "+c+(n%5>3?n%4*4:2-n/5));}main(i){for(;i<100;f(12,4))f(0,i/10),f(6,i++%10);puts("C");}JavaScript, 123
Inspirado por una versión más larga que encontré en un grupo de noticias polaco (al menos, Chrome pensó que era polaco).
fuente
Q (
8180)2do corte:
1er corte:
fuente
Pitón, 168
Explicación
Usando estos valores, tome el valor más grande no mayor que n y reste de n. Repita hasta que n sea 0.
fuente
r=lambda n,l,v:n and(n<v[0]and r(n,l[1:],v[1:])or l[0]+r(n-v[0],l,v))or""Guarda dos personajes. De lo contrario, muy agradable.Rubí 1.9,
140132Esto literalmente cuenta del 1 al 100 en números romanos. Comienza con una cadena en blanco, luego se repite agregando "I" y luego aplica repetidamente una serie de reglas de sustitución, agregando efectivamente 1.
Editar: se agregó el número de versión, ya que
?Isolo funciona en 1.9, y se usaron los cambios de @ Howard para recortar algunos caracteres.fuente
r while->0while,r.sub!(*q)->r.sub! *q. También puede arrastrar la impresión dentro del bucle y usarla en100.times{...}lugar de la declaración del mapa.(%w[IIII VIV XXXX LXL]<</(.)((?!\1)[^I])\1/).zip(%w(IV IX XL XC)<<'\2')ahorra 7 caracteres.Ruby 112 caracteres
Básicamente usando el
to_romanmétodo explicado aquí , pero usando una matriz comprimida por brevedad.fuente
Mathematica
159 150142Solución incorporada :
IntegerString38 caracteresfuente
perl 205
Golfizado:
fuente
MUMPS 184
Mismo algoritmo que @cardboard_box, de quien tomé la explicación literalmente:
Explicación
Usando estos valores, tome el valor más grande no mayor que n y reste de n. Repita hasta que n sea 0.
fuente
R , 85 bytes
Pruébalo en línea!
Utiliza la
utilsvariable de paquete aleatorio.romanspara obtener los valores de los números romanos, pero realiza la conversión por sí mismo; el enfoque integrado sería de 20 bytes:cat(as.roman(1:100))fuente
cat(paste(as.roman(1:100)))o simplementeas.roman(1:100). Extraño.catindican que realiza menos conversión queprinty solo funciona enatomicvectores, ¡eso explica esto!APL 128
Probé una solución de indexación en APL:
Puede ser 4 bytes más corto en el índice de origen 0 en lugar de 1, pero el espacio real es la generación de la matriz de índice a través de:
¡Hasta ahora no he podido generar los índices sobre la marcha!
fuente
LaTeX (138)
fuente
Python, 125
fuente
PHP,
3837 bytes<ol type=I><?=str_repeat("<li>",100);-1 byte gracias a @manatwork
La misma idea que la respuesta de Patrick , pero en un lenguaje más compacto. Beats Mathematica !
Pruébalo en línea!
fuente
;, luego no es necesario?>.VBA (Excel), 245 bytes
Función creada para repetición y reemplazo - 91 bytes
Function s(a,b):s=String(a,b):End Function Function b(x,y,z):b=Replace(x,y,z):End Functionusando la ventana inmediata ( 154 bytes )
p="I":for x=1to 100:?b(b(b(b(b(b(b(b(s(x,p),s(100,p),"C"),s(90,p),"XC"),s(50,p),"L"),s(40,p),"XL"),s(10,p),"X"),s(9,p),"IX"),s(5,p),"V"),s(4,p),"IV"):nextfuente
Java (OpenJDK 8) , 152 bytes
Pruébalo en línea!
Explicación:
fuente
TeX, 354 bytes
Alguna explicación: TeX proporciona un comando incorporado
\romannumeralpara convertir números a números romanos. Como la pregunta no permite usar funciones integradas, el código anterior es una versión desarrollada del mismo algoritmo que el compilador TeX original de Knuth usa para\romannumeral(ver TeX: El Programa , § 69,print_roman_int) re-implementado en TeX.Como quiere dejar la alegría de desconcertar cómo funciona este código para el lector, Knuth se niega a dar una explicación de esta parte del código. Así que haré lo mismo y solo daré una versión no modificada y ligeramente modificada, que está más cerca del original que el código anterior:
fuente