Skip to content

Instantly share code, notes, and snippets.

@gabriel-tincu
Created November 6, 2017 19:03
Show Gist options
  • Save gabriel-tincu/6be23f8a8d3684e0a81b5ef1cab10928 to your computer and use it in GitHub Desktop.
Save gabriel-tincu/6be23f8a8d3684e0a81b5ef1cab10928 to your computer and use it in GitHub Desktop.
import re
mapping = {
'i': (1, 1, 1),
'v': (5, 5, 1),
'x': (10, 1, 2),
'l': (50, 5, 2),
'c': (100, 1, 3),
'd': (500, 5, 3),
'm': (1000, 1, 4)
}
def get_same_degree_val(typ, degree):
for x in mapping:
if mapping[x][2] == degree and typ != mapping[x][1]:
return x
def read_chunk(rom_str, prev_degree=None):
first = rom_str[0]
s = 0
val, typ, degree = mapping[first]
if prev_degree and degree >= prev_degree:
raise Exception('malformed input: prev {} vs current {} in degrees for {}'.format(prev_degree, degree, rom_str))
if typ == 5:
same_degree = get_same_degree_val(typ, degree)
s += val
re_m = '^'+first+same_degree+'{0,3}'
match = re.match(re_m, rom_str, re.I).group()
s += (len(match)-1)*mapping[same_degree][0]
out = rom_str[len(match):]
else:
if len(rom_str) == 1:
return val, degree, ''
if rom_str[1] != first and mapping[rom_str[1]][2] > degree:
if mapping[rom_str[1]][2] == degree+1:
return mapping[rom_str[1]][0] - val, degree, rom_str[2:]
else:
raise Exception('malformed input')
re_m = '^'+first+'{,3}'
match = re.match(re_m, rom_str).group()
s = len(match) * val
out = rom_str[len(match):]
return s, degree, out
def convert_roman(rom_str):
degree = None
val = 0
while True:
cur_val, degree, rom_str = read_chunk(rom_str, degree)
val += cur_val
if not rom_str:
break
if degree == 1 and rom_str:
raise Exception('malformed input')
return val
print(convert_roman('cccviii'.lower()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment