42 lines
1.1 KiB
Python
42 lines
1.1 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
#oneoffs = set(["D", "CD", "L", "XL", "V", "IV"])
|
||
|
roman_numerals = {"M" : 1000, "CM" : 900,
|
||
|
"D" : 500, "CD" : 400,
|
||
|
"C" : 100, "XC" : 90,
|
||
|
"L" : 50, "XL" : 40,
|
||
|
"X" : 10, "IX" : 9,
|
||
|
"V" : 5, "IV" : 4,
|
||
|
"I" : 1}
|
||
|
|
||
|
def parse(path):
|
||
|
with open(path) as f:
|
||
|
return f.read().split("\n")
|
||
|
|
||
|
def roman2int(num):
|
||
|
rn = roman_numerals
|
||
|
r = 0
|
||
|
for dig, i in zip(num, num[1:]+"I"):
|
||
|
r += rn[dig] * (-1 if rn[dig] < rn[i] else 1)
|
||
|
return r
|
||
|
|
||
|
def int2roman(num):
|
||
|
rnum = str()
|
||
|
pairs = list(roman_numerals.items())
|
||
|
pairs.sort(key = lambda x: -x[1])
|
||
|
for dig, val in pairs:
|
||
|
while val <= num:
|
||
|
rnum += dig
|
||
|
num -= val
|
||
|
#if rnum in oneoffs:
|
||
|
#break
|
||
|
return rnum
|
||
|
|
||
|
def main(path):
|
||
|
nums = parse(path)
|
||
|
min_nums = map(int2roman, map(roman2int, nums))
|
||
|
return sum(map(len, nums)) - sum(map(len, min_nums))
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
print(main("data/089_roman_numerals.txt"))
|