Skip to content

Instantly share code, notes, and snippets.

@drmad
Created September 25, 2013 15:30
Show Gist options
  • Save drmad/6701369 to your computer and use it in GitHub Desktop.
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 :)
# ...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