In: Computer Science
A Roman numeral represents an integer using letters.
Examples are XVII to represent 17, MCMLIII for 1953, and MMMCCCIII
for 3303. By contrast, ordinary numbers such as 17 or 1953 are
called Arabic numerals. The following table shows the Arabic
equivalent of all the single-letter Roman numerals:
M 1000 X 10
D 500 V 5
C 100 I 1
L 50
When letters are strung together, the values of the letters are
just added up, with the following exception. When a letter of
smaller value is followed by a letter of larger value, the smaller
value is subtracted from the larger value. For example, IV
represents 5 - 1, or 4. And MCMXCV is interpreted as M + CM + XC +
V, or 1000 + (1000 - 100) + (100 - 10) + 5, which is 1995. In
standard Roman numerals, no more than three consecutive copies of
the same letter are used. Following these rules, every number
between 1 and 3999 can be represented as a Roman numeral made up of
the following one- and two-letter combinations:
M 1000 X 10
CM 900 IX 9
D 500 V 5
CD 400 IV 4
C 100 I 1
XC 90
L 50
XL 40
Write a Python code with a class to represent Roman numerals. The
class should have two constructors. One named “toArabic” constructs
a Roman numeral from a string like "XVII" to “seventeen” or
"MCMXCV" to “one thousand nine hundred ninety-five”. It should
throw an exception if the string is not a legal Roman numeral. The
other constructor named “toInt” constructs a Roman numeral to an
integer such as "XVII" to “17” or "MCMXCV" to “1995”. It should
throw an exception if the integer result is outside the range 1 to
3999.
Please find the program below, i have added 2 tests for MCMXCV and XVII, you can change them as per your wish:
class Roman: def __init__(self, str_val): self.str_val = str_val # get the decimal value of the Roman character def value(self, r): if r == 'I': return 1 if r == 'V': return 5 if r == 'X': return 10 if r == 'L': return 50 if r == 'C': return 100 if r == 'D': return 500 if r == 'M': return 1000 return -1 # convert the given Roman string to decimal number def to_decimal(self): res = 0 i = 0 while i < len(self.str_val): s1 = self.value(self.str_val[i]) if (i + 1) < len(self.str_val): s2 = self.value(self.str_val[i + 1]) if s1 >= s2: res = res + s1 i = i + 1 else: res = res + s2 - s1 i = i + 2 else: res = res + s1 i = i + 1 return res # convert the decimal number to english words def number_to_words(self, num): d = {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', 11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen', 15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen', 19: 'nineteen', 20: 'twenty', 30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninety'} k = 1000 m = k * 1000 b = m * 1000 t = b * 1000 assert (0 <= num) if num < 20: return d[num] if num < 100: if num % 10 == 0: return d[num] else: return d[num // 10 * 10] + '-' + d[num % 10] if num < k: if num % 100 == 0: return d[num // 100] + ' hundred' else: return d[num // 100] + ' hundred and ' + self.number_to_words(num % 100) if num < m: if num % k == 0: return self.number_to_words(num // k) + ' thousand' else: return self.number_to_words(num // k) + ' thousand, ' + self.number_to_words(num % k) if num < b: if (num % m) == 0: return self.number_to_words(num // m) + ' million' else: return self.number_to_words(num // m) + ' million, ' + self.number_to_words(num % m) if num < t: if (num % b) == 0: return self.number_to_words(num // b) + ' billion' else: return self.number_to_words(num // b) + ' billion, ' + self.number_to_words(num % b) if num % t == 0: return self.number_to_words(num // t) + ' trillion' else: return self.number_to_words(num // t) + ' trillion, ' + self.number_to_words(num % t) raise AssertionError('num is too large: %s' % str(num)) def to_arabic(self, str_val): return to_decimal(self, str_val) s = "MCMXCV" r = Roman(s) print("Test 1:") print("Integer form of Roman Numeral " + s + " is : " + str(r.to_decimal())) print(str(r.to_decimal()) + " in words is : ") print(r.number_to_words(r.to_decimal())) s = "XVII" r = Roman(s) print("Test 2:") print("Integer form of Roman Numeral " + s + " is : " + str(r.to_decimal())) print(str(r.to_decimal()) + " in words is : ") print(r.number_to_words(r.to_decimal()))
Program screenshot along with the output, follow the line numbers:
Output:
Please provide a feedback by clicking on the feedback button