Created
September 25, 2013 15:30
-
-
Save drmad/6701369 to your computer and use it in GitHub Desktop.
Convertidor simple de decimal a romanos. Este chiste salió de un Ruby Coding Dojo organizado por @lshimokawa , quien me dejó picado con este algoritmo :)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ...then the mortals started the coding: utf-8 was | |
# chosen, because their gods love to use diæreses | |
# | |
# Romanos, por Oliver Etchebarne -- ¡Ahora con comentarios! ¡Yay! | |
# | |
# http://drmad.org | |
class Romanos | |
def self.generar ( numero ) | |
# Valor posicional del dígito que estamos analizando | |
vp = 0 | |
# Array de las letras romanas, indexadas por su valor posicional. | |
# La primera letra es la unidad, las segunda es la unidad * 5 | |
# | |
# Al parecer, ninguna cantidad romana original fue mayor a 1399... | |
# | |
# Para ser tecnológicamente correctos, deberíamos usar los caracteres | |
# Unicode para números romanos. En tal caso, debería quedar asi: | |
# | |
# letras = %w"ⅠⅤ ⅩⅬ ⅭⅮ Ⅿ-" | |
# | |
letras = %w"IV XL CD M-" | |
# Aquí quedará el número romano final | |
palabra = '' | |
# Esto no es realmente necesario, pero puede ser útil en alguna | |
# circunstancia mantener el número original. | |
n = numero | |
# Empezamos... | |
while n > 0 | |
# Sacamos el dígito de menor valor posicional | |
digito = n % 10 | |
# Seleccionamos el grupo de símbolos que le corresponde | |
sel = letras[vp] | |
# Si el dígito es < 4 simplemente repetimos la unidad. Esto trae un | |
# bonus: Si el dígito es 0, simplemente no aparece. | |
if digito < 4 | |
letra = sel[0] * digito | |
# El 4 tiene una forma especial, juntamos la unidad con sun "cinco" | |
elsif digito == 4 | |
letra = sel[0] + sel[1] | |
# Del 6 al 8, es el "cinco" más la unidad repetida. Esto también | |
# trae un bonus: Si el dígito es 5, entonces la unidad no se repite. | |
elsif digito > 4 and digito < 9 | |
letra = sel[1] + sel[0] * (digito - 5) | |
# Solo queda un único caso, el 9. Sacamos la letra del siguiente | |
# valor posicional. ¡OJO esto fallará al intentar crear un número | |
# muy grande! | |
else | |
letra = sel[0] + letras[vp+1][0] | |
end | |
# Y colocamos la(s) letra(s) en la palabra. Al revés, ya que | |
# los numeros romanos crecen hacia la derecha. | |
palabra = letra + palabra | |
# Dividimos el número, para eliminar el dígito de menor valor | |
# posicional, y continuar con el siguiente. | |
n /= 10 | |
# Aumentamos el valor posicional | |
vp += 1 | |
end | |
# Y listo! | |
return palabra | |
end | |
end | |
# Algunas pruebas | |
[47, 1910, 1954, 1990, 2008].each do |n| | |
puts "#{n} en romanos es " + Romanos.generar(n) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment