Objetivo:
escribir una función que tome un número como entrada y devuelva un número romano de mano corta para ese número como salida.
Símbolos de números romanos:
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1,000
Para un ejemplo de lo que quiero decir cuando digo "números romanos abreviados", consideremos encontrar un número romano para representar 1983, porque ese es el año en que nací. Una opción es hacer esto de la manera normal (10 letras):
1983 = MCMLXXXIII = ( 1000-100 + 1000 + 50 + 30 + 3)
La otra opción es hacerlo de forma abreviada (6 caracteres):
1983 = MXVIIM = (1000 - (10 + 10) + 1000 + 3)
¿¿¡¡¿¡¿Sabes qué significa esto?!?!!?? ¡Si fuera romano, podría haber guardado 4 caracteres cada vez que escribiera mi fecha de nacimiento! Woot Woot !!
Sin embargo, antes de adelantarme en la emoción, tengo una pregunta que escribir, por lo que probablemente debería definir las reglas de números romanos abreviados para que todos estemos en la misma página:
Reglas de números romanos de mano corta:
- Siempre considere los símbolos de izquierda a derecha hasta que no haya más caracteres para considerar.
- Si no hay símbolos de mayor valor a la derecha del símbolo actual:
- Agregue el valor del símbolo actual al total acumulado de este número romano.
- Si hay símbolos de mayor valor a la derecha del símbolo que está considerando:
- Ubique el símbolo de mayor valor más a la derecha a la derecha del símbolo actual
- Considere todos los caracteres hasta ese símbolo como un número romano
- Calcule el valor de ese número romano usando estos pasos
- Reste el valor de ese número romano del total acumulado de este número romano.
- Pasa al siguiente símbolo después del grupo que acabas de considerar
- Cada número romano debe tener al menos 1 símbolo.
- ¡Eso es! ¡Todo lo que siga estas reglas será aceptado!
Ejemplos:
IIIIV = (-(1+1+1+1)+5) = 1 //Don't ask me why you'd want to do this!
VVX = (-(5+5) + 10) = 0 //Who said you couldn't represent 0 with roman numerals?!!?
VVXM = (-(-(5+5) + 10) + 1000) = 1000 //Again...don't ask me why you'd want to do this!
MXIIXMI = (1000-(10-(1+1)+10)+1000+1) = 1983 //Ahhh...such a great year :)
Reglas de preguntas:
Realice una función que tome un solo número como entrada y devuelva un número romano para ese número como salida utilizando las reglas anteriores. Calcule el codeGolfScore de esta función.
example input: 2011 example possible output: MMXI another possible output: MMVVIVV //(2000 + 10 - 4 + 5)
Usando su función de la regla 1, genere los números romanos entre -1000 (es cierto, NEGATIVO mil) y 3000. Luego, sume la longitud de los caracteres de estos números romanos para obtener su totalCharacterCount . Aquí hay un pseudocódigo para aclarar:
totalCharacterCount = 0; for(currentNumber = -1000; currentNumber <= 3000; currentNumber++){ totalCharacterCount += getRomanNumeral(currentNumber).length; } return totalCharacterCount;
finalScore = codeGolfScore + totalCharacterCount
- ¡El puntaje final más bajo gana!
Nota: Como el recuento total de caracteres estará en más de diez mil, el algoritmo de longitud de caracteres debe ser la máxima prioridad. Los puntajes de código de golf son solo el factor decisivo en caso de que varios usuarios encuentren el algoritmo o algoritmos óptimos que están cerca uno del otro.
Buena suerte y diviértete en tus celebraciones MMXII mañana por la noche.
fuente
DDDDM
significa-1000
?""
permitido cero o tenemos que usarVVX
o algo equivalente?IXV = -(-1 + 10) + 5 = -4
(victorias más a la derecha) oIXV = -1 + 10 + 5 = 14
(victorias de mayor valor)?Respuestas:
Haskell, 25637 (= 268 + 25369)
26045 (= 222 + 25823)para ser utilizado como por ejemplo
Puede evaluar la suma de la longitud con el sencillo
Lo cual toma algo del orden de un minuto.
fuente
C ++, 345 caracteres de código, 25021 dígitos de números romanos = 25366
desobuscado un poco, con un controlador:
V
calcula el valor numérico de una cadenas
de longitud de un número romano dadoL
. Las cadenas están codificadas en base 7 (el primer dígito es s% 7, el segundo dígito es s / 7% 7, ...). Cada dígito está codificado con I = 0, V = 1, ..., M = 6.f
hace una enumeración de fuerza bruta de posibles cadenas de números romanos para encontrar una queV
evalúen
.El número total de dígitos de números romanos es óptimo. El número romano más largo necesario para [-1000,3000] es de 11 dígitos (por ejemplo, -827 = CMDDMLXXIII), lo que demora aproximadamente 5 minutos en mi máquina.
fuente
LMCLXXIII
como la respuesta a-777
. Lo había leído como-50+1000-100+50+10+10+3 = 923 ≠ -777
, solo con "el más alto valor " en lugar de " más alto " da-777
. ¡Pero eso fue justo lo que pediste en los comentarios!VVVXI
para-4
cuandoIXVX
en realidad es más corto, como acabo de notar) - pero eso es perfectamente legal.Rubí, 25987 (= 164 + 25823)
Puede llamar
r
directamente para obtener los resultados. La suma sobre el rango especificado rindecuál es la suma óptima como con las otras soluciones.
fuente
C # 23537 (639 caracteres de código + 22898 caracteres de salida)
Calcular:
Enumerable.Range(-1000, 3000).Sum(i => M.R(i).Length);
fuente