project-euler/089_roman_numerals.py

42 lines
1.1 KiB
Python
Raw Normal View History

2023-03-26 22:59:33 +02:00
#!/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"))