RosettaCodeData/Task/Roman-numerals-Decode/Eiffel/roman-numerals-decode.e
2015-02-20 00:35:01 -05:00

111 lines
2.3 KiB
Text

class
APPLICATION
create
make
feature {NONE} -- Initialization
make
local
numbers: ARRAY [STRING]
do
numbers := <<"MCMXC", "MMVIII", "MDCLXVI",
-- 1990 2008 1666
"MMMCLIX", "MCMLXXVII", "MMX">>
-- 3159 1977 2010
across numbers as n loop
print (n.item +
" in Roman numerals is " +
roman_to_decimal (n.item).out +
" in decimal Arabic numerals.")
print ("%N")
end
end
feature -- Roman numerals
roman_to_decimal (a_str: STRING): INTEGER
-- Decimal representation of Roman numeral `a_str'
require
is_roman (a_str)
local
l_pos: INTEGER
cur: INTEGER -- Value of the digit read in the current iteration
prev: INTEGER -- Value of the digit read in the previous iteration
do
from
l_pos := 0
Result := 0
prev := 1 + max_digit_value
until
l_pos = a_str.count
loop
l_pos := l_pos + 1
cur := roman_digit_to_decimal (a_str.at (l_pos))
if cur <= prev then
-- Add nonincreasing digit
Result := Result + cur
else
-- Subtract previous digit from increasing digit
Result := Result - prev + (cur - prev)
end
prev := cur
end
ensure
Result >= 0
end
is_roman (a_string: STRING): BOOLEAN
-- Is `a_string' a valid sequence of Roman digits?
do
Result := across a_string as c all is_roman_digit (c.item) end
end
feature {NONE} -- Implementation
max_digit_value: INTEGER = 1000
is_roman_digit (a_char: CHARACTER): BOOLEAN
-- Is `a_char' a valid Roman digit?
local
l_char: CHARACTER
do
l_char := a_char.as_upper
inspect l_char
when 'I', 'V', 'X', 'L', 'C', 'D', 'M' then
Result := True
else
Result := False
end
end
roman_digit_to_decimal (a_char: CHARACTER): INTEGER
-- Decimal representation of Roman digit `a_char'
require
is_roman_digit (a_char)
local
l_char: CHARACTER
do
l_char := a_char.as_upper
inspect l_char
when 'I' then
Result := 1
when 'V' then
Result := 5
when 'X' then
Result := 10
when 'L' then
Result := 50
when 'C' then
Result := 100
when 'D' then
Result := 500
when 'M' then
Result := 1000
end
ensure
Result > 0
end
end