- Published on
Roman Numerals Conversion
- Authors
- Name
- Humam Fauzi
Roman numerals, like its arabian counter part, have the largest number on the left hand side and the lowest on the right hand side. However roman numerals have caveat which it sometimes implies subtraction. For example the roman numerals for number 4 is IV
which is 5 (represented as V
) subtracted by 1 (represented as I
). This also happen in number 9 which represented as IX
.
How we construct a program that takes string of valid roman numerals e.g.
III
,IV
,XIV
to its arabic numerals.
We can begin by creating an empty function
package roman
func romanNumerals(roman string) int {
return 0
}
or in python we can write
def roman_numerals(roman :string) int:
return 0
One of the approach we can take is creating a Map between roman numerals to its arabic counter part. You can choose to use Rune data type but for now I use regular string
var romanMap = map[string]int{
"I": 1,
"X": 10,
}
for python, we can use built in dictionary data type to map roman numerals to arabic numerals.
roman_map = {
"I": 1,
"X": 10,
}
The first instinct we have is to iterate the string from first to end. In each of its character, we translate it to arabic numerals and sum it to get the final number.
package roman
var romanMap = map[string]int{
"I": 1,
"X": 10,
}
func romanNumerals(roman string) int {
final := 0
for _, value := roman {
final += romanMap[string(value)]
}
return final
}
roman_map = {
"I": 1,
"X": 10,
}
def roman_numerals(roman :string) int:
final = 0
for char in roman:
final += roman_map[char]
return final
It is a straight answer but we need to handle the subtraction part. If we plug IX
to the program, it wont return the right answer; it would return 11 instead of 9. So how we handle the subtraction part?
There subtraction require additional knowledge that a regular for loop does not have. It require to know whether the next character arabic representation is larger than current one. If the next character is larger, then we the current one is a minus to the sum.
In programming languange, there is risk that we access the index that larger than the array length itself; an out of bound error. Since we want to access the next char, we need to know whether at the end or not to avoid out of bond.
package roman
var romanMap = map[string]int{
"I": 1,
"X": 10,
}
func romanNumerals(roman string) int {
final := 0
totalLength := len(roman)
for index, value := roman {
next := index + 1
num := romanMap[string(value)]
if next == len(roman) {
final += num
break
}
nextNum := romanMap[string(roman[next])]
if num > nextNum {
final += num
} else {
final -= num
}
}
return final
}
To handle next array, there are two additional ifs, first if to handle if we at the last digit and we need to avoid out of bond error. The next if is the one handle if the current character is larger that next one. We translate the current character to num with romanMap[string(value)]
and next character to num with romanMap[string(roman[next])]
. We can do this in python
roman_map = {
"I": 1,
"X": 10,
}
def roman_numerals(roman :string) int:
final = 0
for (index, char) in enumerate(roman):
next_index = index + 1
num := roman_map[char]
if next_index == len(roman):
final += num
break
next_num := romanMap[roman[next_index]]
if num > next_num:
final += num
else:
final -= num
return final