Конвертатор чисел из арабских в Римские, проблема с девятками
Написал прогу, которая, в зависимости от разряда и первого числа этого разряда, записывает в ответ тот или иной вариант записи числа. Так вот, все работает как надо, кроме девяток и чисел после 4 тысяч. Было бы неплохо это исправить, т.к. сам проблему не нашел. Надеюсь на максимально простой вариант и желательно - объяснение. Код ниже.
inp_='3948'
roman_num={1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M'}
#answ_dict={}
answer='' # Var for exit
multiplier=1 # Var for optimize code
counter=0 # NVRMND
for i in range(len(inp_)-1): # Setting the multiplier
multiplier=multiplier*10
#print(multiplier)
while len(inp_)!=0: # While we have at least one digit
num=int(inp_[0]) # Var for make code simoly for read
if 0<=(num-5)<9: # If number can be presented as summ of 5 and other digits before 9
#multiplier=multiplier/10
answer+=roman_num[5*multiplier]+roman_num[multiplier]*(num-5) # Adding to output number from multiplier's class multiple 5 and adding numbers from that class multiple 1
print(f'5, {answer}, {multiplier}')
#multiplier=multiplier*10
elif num==9: # If digit is 9, we can present it as N⁞5+N(by multiplier)
answer+=roman_num[multiplier]+roman_num[multiplier*10] # Adding to output number from multiplier's class and adding number from next one class
print(f'9, {answer}, {multiplier}')
elif num==4: # If digit is 4, we can pesent it as:
if len(inp_)>=4: # If digit from thousands
answer+=roman_num[multiplier]*num # Number from multiplier's class printed num times
else:
answer+=roman_num[multiplier]+roman_num[multiplier*5] # N⁞5+N(by multiplier)
print(f'4, {answer}, {multiplier}')
#multiplier=multiplier*10
else: # If num - digit 1-3, we can just write it num times
answer+=roman_num[multiplier]*num # Adding number from multiplier's class to output by adding number num times
print(f'else, {answer}, {multiplier}')
multiplier=multiplier/10 # Decrease class of multiplier
inp_=inp_[1:] # Delete previous class
print(num-5)
print(answer)
Ответы (2 шт):
Автор решения: Zhihar
→ Ссылка
def Arabic2Roman(number):
# арабские цифры
arab = [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000];
# римские цифры
roman = ['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'];
# если число нулевое - выдать пустой результат
if number == 0:
return '';
result = ""
pos = len(arab) - 1;
while number > 0:
if number >= arab[pos]:
result += roman[pos]
number -= arab[pos]
else:
pos -= 1
# вернуть результат
return result
print(Arabic2Roman(1999))
по идее можно, если есть такие числа, ввести 10000, 1000000 и т.д., алгоритм не изменится
Автор решения: Serg Bocharov
→ Ссылка
Тогда уж можно во все стороны гонять числа (оригинал принадлежит agalen):
CONV_TABLE = ((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 arab_to_roman( number ):
if number <= 0: return ''
ret = ''
for arab, roman in CONV_TABLE:
while number >= arab:
ret += roman
number -= arab
return ret
def roman_to_arab( txt ):
txt = txt.upper()
ret = 0
for arab, roman in CONV_TABLE:
while txt.startswith( roman ):
ret += arab
txt = txt[ len( roman ): ]
return ret
for i in ( 0, 4, 8, 9, 31, 46, 99, 583, 888, 1668, 1989, 2009, 2010, 2011, 3999 ):
arab = arab_to_roman( i )
roman = roman_to_arab( arab )
print (i, arab, roman)