Buddha

Buddha
Seek

Tuesday, January 27, 2015

Find Decimal value from a Roman Numeral Number , iterative and recursive solutions

The problem : Given a roman value, find the corresponding decimal value.

Sample Input : XVII
Sample Output : 17

Sample Input : XIV
Sample Output : 14

Solution:

If we first look, there are certain roman values representing certain decimal values, direct mapping, cant do anything about that. So we need a map. Like the one below

map = {'I':1, 'V':5 , 'X':10, 'L':50, 'C':100}

Next gotcha, as long as the values are decreasing or constant, with index, we just keep adding the values. However, if the values increase, we need to do things differently. What needs to be done differently ? We need to subtract the lower value from higher value.

e.g.  if number is VI , index 0 has ' V ' and index 1 has ' I ' , values are decreasing, we need to add value of V + value of I , which is, 5 + 1 = 6

if number is IV, index 0 has ' I ' and index 1 has ' V ' which is increasing, we need to do value of V - value of I , which is 5 - 1 =  4

So, in general, we need to know the next Value.

Iterative Solution:

def returndec(roman):
charlist = list(roman)
num = 0
for i in range(len(charlist)):
if i+1 == len(charlist):
num += map[charlist[i]]
else:
if map[charlist[i]] >= map[charlist[i+1]]:
num += map[charlist[i]]
else:
num -= map[charlist[i]]
return num

Here, we see that indexes i and i+1 are being compared as long as i+1 is in bounds. If the order is decreasing we do  num = num - charlist[i] , which is essentially, adding up negative of lower value to higher value, which is in other words subtracting lower value from higher value.

The recursive solution gets more interesting. Here we need to track the sum as we toss it to each function as a param, but when we return , we need to return the sum, as well as value of first index. Let me demonstrate:

for roman number "XIX"

To calculate func("XIX") we need to calculate either
a)  X + func("IX")
OR
b) -X + func ("IX")

depending on whether X is greater than I or not

Recursive Solution:

def returnDecRec(roman , num):
print "roman ", roman, " num ", num
if not roman:
return (num, 0)
val = map[list(roman)[0]]
num, lastVal = returnDecRec(roman[1:], num)
if lastVal > val:
return (num - val, val)
else:
return (num + val, val)

In the above case, we return sum until the subset of string, plus value added.
Another way to recurse would be to pass the value added in the function parameter.

Something like :
def returnDecRec(roman, num, val)