Files
exercism/python/roman-numerals/roman_numerals.py
2019-07-18 02:26:10 -05:00

24 lines
1.1 KiB
Python

numerals = {1 : 'I', 5 : 'V', 10 : 'X', 50 : 'L', 100 : 'C', 500 : 'D', 1000 : 'M', 5_000 : '_V', 10_000 : '_X', 50_000 : '_L', 100_000 : '_C', 500_000 : '_D', 1_000_000 : '_M'}
match = {'V' : 'I', 'X' : 'I', 'L' : 'X', 'C' : 'X', 'D' : 'C', 'M' : 'C'}
def first(n, s=0):
return (n, 10 ** s) if n < 10 else first(n // 10, s=s+1)
def roman(n):
if n % 10 != 0 and len(str(n).strip('0')) > 1:
temp = map(lambda item : int(item[1] + '0' * (len(str(n)) - 1 - item[0])), enumerate(str(n)))
return ''.join(map(roman, temp))
if n in numerals: return numerals[n]
if n > 3 and (first(n)[0] + 1) * first(n)[1] in numerals:
top = (first(n)[0] + 1) * first(n)[1]
if n >= 4000:
if numerals[top].startswith('_'):
return '_' + match[numerals[top][1:]] + numerals[top]
return match[numerals[top]] + numerals[top]
else:
res = ''
while n > 0:
best = max(numerals.keys(), key=lambda item : 0 if item > n else item)
n -= best
res += numerals[best]
return res