Resumen
Los antiguos romanos idearon un sistema numérico usando letras latinas, que les sirvió bien, y que todavía es utilizado por la civilización moderna, aunque en un grado mucho menor. En el momento de su uso, los romanos habrían tenido que aprender a usar y manipular estos números para ser de gran utilidad en muchas aplicaciones. Por ejemplo, si un hombre poseía 35 bueyes y adquirió 27 más, ¿cómo conocería el nuevo total además de contarlos a todos? ( Ok, eso y usar un ábaco ... ) Si los romanos pudieran hacerlo, seguramente también podemos resolverlo.
Objetivo
Escribir el algoritmo / función / programa más corto que agregará dos números romanos y generará el resultado sin convertir la representación de cadena de cualquier entrada en un número.
Reglas / restricciones
Debido a las inconsistencias históricas / pre-medievales en el formato, voy a describir algunas reglas no estándar (por uso moderno) para la ortografía. Consulte la guía de valores a continuación como ejemplo.
- Las letras I, X, C y M se pueden repetir hasta cuatro veces seguidas, pero no más. D, L y V nunca pueden repetirse.
- La letra inmediatamente a la derecha de otra letra en la representación romana tendrá el mismo valor o menor que el de la izquierda.
- En otras palabras,
VIIII == 9
peroIX != 9
y es inválido / no permitido.
- En otras palabras,
- Todos los valores de entrada serán 2,000 (MM) o menos; no es necesaria una representación para números mayores que M.
- Todos los valores de entrada serán un número romano válido, de acuerdo con las reglas anteriores.
- No puede convertir ningún número a decimal, binario o cualquier otro sistema de números como parte de su solución (puede usar dicho método para VERIFICAR sus resultados).
- Este es el código de golf, por lo que gana el código más corto.
Guía de valor
Symbol Value
I 1
II 2
III 3
IIII 4
V 5
VIIII 9
X 10
XIIII 14
XXXXIIII 44
L 50
LXXXXVIIII 99
C 100
D 500
M 1,000
Ejemplos
XII + VIII = XX (12 + 8 = 20)
MCCXXII + MCCXXII = MMCCCCXXXXIIII (1,222 + 1,222 = 2,444)
XXIIII + XXXXII = LXVI (24 + 42 = 66)
Si necesita más aclaraciones, por favor pregunte.
fuente
Respuestas:
APL (
5956)Entrada en una línea (es decir
XII + XII
, aunque+
no es necesario).Editar: cambio de turno para rotar para guardar tres caracteres: solo importa cuando la respuesta ≥ 5000, lo que nunca debería suceder ya que la pregunta dice que los valores de entrada siempre serán ≤ 2000. El único efecto es que ahora "se desborda" en 5000, dando 5000 = 1, 5001 = 2, etc.
(Realmente no creo que los romanos lo hicieran de esta manera ... APL es más algo para los antiguos egipcios, creo :))
Explicación:
⍞
: obtener la entrada del usuario(N←'MDCLXVI')∘=¨
: almacena 'MDCLXVI' en N. Devuelve, para cada carácter de la cadena de entrada, un vector con un 1 en el lugar donde el carácter corresponde a uno de 'MDCLXVI', y 0 en caso contrario.⊃+/
: Suma los vectores y desencapsula. Ahora tenemos un vector con información sobre cuántos de cada número romano tenemos. Es decir, si la entrada fueXXII XIIII
, ahora tenemos:{
...:
...⋄
...}
es una función con una construcción if-else.D←7⍴5 2
:D
es el vector5 2 5 2 5 2 5
. Esta es la cantidad de números romanos que no están permitidos. Es decir, si tiene 5I
s, son demasiados, y si tiene 2V
s, también son demasiados. Este vector también es el factor de multiplicación para cada número romano, es decir, aV
vale 5I
sy anX
vale 2V
s.∨/K←⍵≥D
:K
es el vector donde hay un 1 si tenemos demasiados números romanos de cierto tipo.∨/
O este vector juntos.K×D
: Multiplica K por D. Este vector tiene ceros donde no tenemos demasiados números romanos, y la cantidad de números romanos donde los tenemos.⍵+(1⌽K)
: Gire K hacia la izquierda en 1 y agréguelo a la entrada. Para cada número romano que tenemos demasiados, esto agregará uno del siguiente más alto.⍵+(1⌽K)-K×D
: Resta esto del otro vector. El efecto es, por ejemplo, si tiene 6I
s, agregará unoV
y eliminará 4I
s.∇
: Recurse.⋄⍵
: Pero siK
todos fueron ceros, entonces ⍵ representa un número romano válido, así que devuelve ⍵.N⍴⍨¨
: Para cada elemento del vector resultante, cree muchos de los números romanos correspondientes.,/
: Une estos vectores para deshacerse de los espacios feos en la salida.fuente
Python, 100
Toma una cadena de entrada (p . Ej.
VIII + XII
OVIII + XII =
).fuente
Perl, 132 caracteres
Declara la función
s
que toma cualquier número de argumentos y los suma. Bastante sencillo: agrega la entrada, reduce todo aI
sy luego restaura inmediatamente los números romanos. (¡Espero que esto no cuente como usar el sistema de números unarios!)fuente
Ruby,
8582 caracteresEsta versión toma la entrada en STDIN como una sola cadena (por ejemplo
XXIIII + XXXXII
) e imprime la salida en STDOUT.El segundo es una implementación como una función. Toma dos (o más) cadenas y devuelve los valores sumados. Uso:
fuente
GNU Sed, 131 caracteres
fuente
Python, 174 caracteres
Un algoritmo muy simple: cuente cada dígito, bucle para manejar el desbordamiento al siguiente, imprimir.
Lee desde la entrada estándar. Algo así
XVI + CXX
funcionaría (ignora cualquier cosa excepto los números, por lo+
que no se necesita realmente).fuente
Scala 150
invocación:
Versión sin golf:
fuente
JavaScript
195179Mi sistema es bastante rudimentario, reduzco todos los números romanos a una serie de
I
ambos números, unirlos y luego revertir el proceso convirtiendo ciertos bloquesI
en sus respectivas versiones más grandes ...Iteración 1
a="IIIII0VV0XXXXX0LL0CCCCC0DD0M".split(0);d=b=>x.replace(g=RegExp((c=z)>b?a[c][0]:a[c],"g"),c>b?a[b]:a[b][0]);x=prompt().replace("+","");for(z=6;0<z;z--)x=d(z-1);for(z=0;6>z;z++)x=d(z+1);alert(x)
Iteración 2
a="IIIII0VV0XXXXX0LL0CCCCC0DD0M".split(0);x=prompt().replace("+","");for(z=-6;6>z;z++)b=0>z?-z:z,c=0>z?~z:z+1,x=x.replace(g=RegExp(b>c?a[b][0]:a[b],"g"),b>c?a[c]:a[c][0]);alert(x)
caracteristicas:
La entrada se ingresa mediante un indicador en forma de
<first roman number>+<second roman number>
(sin espacios), la salida en forma de alerta.p.ej
fuente
VBA, 187 caracteres
fuente
o
solo se usa una vez, puede ahorrar 3 bytes eliminando la asignación y evaluación de la misma y conectándosen Mod r
directamente a laString(
llamada de funciónJavaScript, 190
¡Poner algunas instrucciones dentro de la tercera ranura del
for
operador me permite guardar algunos puntos y comas!Cuando se solicita la entrada, inserta los dos números (los
+
espacios y no son necesarios, pero si los coloca no obtiene un error). Entonces la alerta te muestra la suma.fuente
C ++, 319 caracteres
fuente
PHP, 136 bytes
Pruébalo en línea!
fuente