Saltar al contenido

¿Programa básico para convertir números enteros a números romanos?

Esta es la respuesta más correcta que te podemos compartir, pero primero mírala detenidamente y analiza si se adapta a tu proyecto.

Solución:

Una de las mejores maneras de lidiar con esto es usando el divmod función. Verifica si el número dado coincide con cualquier número romano desde el más alto hasta el más bajo. En cada partido, debe devolver el carácter respectivo.

Algunos números tendrán residuos cuando utilice la función de módulo, por lo que también aplica la misma lógica al resto. Obviamente, estoy insinuando recursividad.

Vea mi respuesta a continuación. yo uso un OrderedDict para asegurarme de que puedo iterar “hacia abajo” la lista, luego uso una recursión de divmod para generar coincidencias. Finalmente yo join todas las respuestas generadas para producir una string.

from collections import OrderedDict

def write_roman(num):

    roman = OrderedDict()
    roman[1000] = "M"
    roman[900] = "CM"
    roman[500] = "D"
    roman[400] = "CD"
    roman[100] = "C"
    roman[90] = "XC"
    roman[50] = "L"
    roman[40] = "XL"
    roman[10] = "X"
    roman[9] = "IX"
    roman[5] = "V"
    roman[4] = "IV"
    roman[1] = "I"

    def roman_num(num):
        for r in roman.keys():
            x, y = divmod(num, r)
            yield roman[r] * x
            num -= (r * x)
            if num <= 0:
                break

    return "".join([a for a in roman_num(num)])

Dando una vuelta:

num = 35
print write_roman(num)
# XXXV

num = 994
print write_roman(num)
# CMXCIV

num = 1995
print write_roman(num)
# MCMXCV

num = 2015
print write_roman(num)
# MMXV

Aquí hay otra manera, sin división:

num_map = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'),
           (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]


def num2roman(num):

    roman = ''

    while num > 0:
        for i, r in num_map:
            while num >= i:
                roman += r
                num -= i

    return roman

# test 
>>> num2roman(2242)
'MMCCXLII'

Actualizar ver la ejecución visualizada

Una versión KISS del algoritmo de Manhattan, sin ninguna noción "avanzada" como OrderedDictrecursión, generadores, función interna y break:

ROMAN = [
    (1000, "M"),
    ( 900, "CM"),
    ( 500, "D"),
    ( 400, "CD"),
    ( 100, "C"),
    (  90, "XC"),
    (  50, "L"),
    (  40, "XL"),
    (  10, "X"),
    (   9, "IX"),
    (   5, "V"),
    (   4, "IV"),
    (   1, "I"),
]

def int_to_roman(number):
    result = ""
    for (arabic, roman) in ROMAN:
        (factor, number) = divmod(number, arabic)
        result += roman * factor
    return result

Una salida prematura podría agregarse tan pronto como number llega a cero y el string la acumulación podría hacerse más pitónica, pero mi objetivo aquí era producir el pedido básico programa.

Probado en todos los números enteros del 1 al 100000, lo que debería ser suficiente para cualquiera.

EDITAR: la versión un poco más pitónica y más rápida a la que aludí:

def int_to_roman(number):
    result = []
    for (arabic, roman) in ROMAN:
        (factor, number) = divmod(number, arabic)
        result.append(roman * factor)
        if number == 0:
            break
    return "".join(result)

Comentarios y valoraciones de la guía

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *