def number_to_numeral(n): """ returns minimal numeral """ remainder = n values = [1000, 500, 100, 50, 10, 5, 1] substractive_cases = [None, 100, 100, 10, 10, 1, 1] symbols = dict(zip(values, ['M', 'D', 'C', 'L', 'X', 'V', 'I'])) numeral = '' for i in range(len(values)): if remainder >= values[i]: # first substractive test if substractive_cases[i] != None and i > 0: if (remainder + substractive_cases[i]) >= values[i-1]: remainder -= (values[i-1] - substractive_cases[i]) numeral += symbols[substractive_cases[i]] + symbols[values[i-1]] # then normal test while remainder >= values[i]: remainder -= values[i] numeral += symbols[values[i]] return numeral for i in range(1, 21): print(number_to_numeral(i)) number_to_numeral(9) number_to_numeral(19) number_to_numeral(400) number_to_numeral(405) number_to_numeral(900) number_to_numeral(1900) def numeral_to_number(numeral): number = 0 values = [1000, 500, 100, 50, 10, 5, 1] symbols = dict(zip(['M', 'D', 'C', 'L', 'X', 'V', 'I'], values)) for ind, num in enumerate(numeral): if not ind == len(numeral) - 1: if symbols[numeral[ind+1]] > symbols[num]: number -= symbols[num] else: number += symbols[num] else: number += symbols[num] return number numeral_to_number('MMMDLXVIIII') number_to_numeral(3569) import urllib2 # the lib that handles the url stuff data = urllib2.urlopen("https://projecteuler.net/project/resources/p089_roman.txt").readlines() # it's a file like object and works just like a file initial_lengths = [] shortest_lengths = [] for line in data: # files are iterable initial_lengths.append(len(line.strip())) n = numeral_to_number(line.strip()) shortest_lengths.append(len(number_to_numeral(n))) sum(initial_lengths) sum(shortest_lengths) sum(initial_lengths) - sum(shortest_lengths)