Roman Numeral to Hindu and Vice Versa
This is a sample problem from the NCC ICT Proficiency Reviewer which I took last year:
Write a program that will convert a Roman number into its equivalent Hindu Arabic number, and vice versa. The program should ask the user what type of number to convert (Roman or Hindu Arabic).
Hindu to Roman is relatively straightforward: match it to the largest equivalent Roman numeral and subtract until you reach zero. Roman to Hindu gets a bit trickier, since you have to read non-numeric values and determine their equivalent normal value. See, it's only in those special instances (XC, XL, IV, IX, etc) that a lower value comes before a higher one (reading left to right). Everything else, it's VIII, XI, LX and such -- in those cases it's simple addition. But in the case of 4's and 9's, the left value is subtracted from the right value, so in IV, 1 is subtracted from 5 to produce 4, in XL 10 is subtracted from 50 to produce 40, and so on.
The following is the Python code for that implementation:
def hindu_to_roman(num):
if not 0 < num < 4000:
return "Invalid input."
temp = num
roman = ""
i = 0
romans = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]
numbers = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
while temp > 0:
if temp < numbers[i]:
i += 1
elif temp >= numbers[i]:
roman += romans[i]
temp -= numbers[i]
return roman
def roman_to_hindu(num):
romans = ["M", "D", "C", "L", "X", "V", "I"]
numbers = [1000, 500, 100, 50, 10, 5, 1]
total = 0
temp = num.upper()
for i in range(len(temp)):
try:
currval = numbers[romans.index(temp[i])]
if i < len(temp) - 1:
nextval = numbers[romans.index(temp[i+1])]
if currval < nextval:
currval *= -1
total += currval
except:
total = "Invalid input."
return total
def main():
choice = input("[1] Roman to Hindu\n[2] Hindu to Roman\n[3] Quit\nChoose: ")
while choice != 3:
if choice == 1:
num = raw_input("Enter a valid Roman numeral. Please? : ")
res = roman_to_hindu(num)
print res
elif choice == 2:
num = input("Enter a positive integer less than 4000: ")
res = hindu_to_roman(num)
print res
elif choice == 3:
pass
else:
print "\nInvalid choice.\n"
choice = input("\n[1] Roman to Hindu\n[2] Hindu to Roman\n[3] Quit\nChoose: ")
main()
Some notes: 3,999 is traditionally the largest Roman number, following that you can only repeat a letter three times: MMMCMXCIX. Removing the check for it -- if not 0 < num < 4000 -- allows you to output larger values with a lot of repeating M's.
This was originally posted at the Far From Neutral blog — No Fun with Roman Numerals