--00504502d48e72e6750473dfb830
Content-Type: text/plain; charset=ISO-8859-1
how about that one (it's a little longish):
class String
def to_roman
str elf.downcase
raise SyntaxError, "Not a roman numeral" unless str /^[mdclxvi]+$/
raise SyntaxError, "Not a roman numeral" if
%w{iiii vv xxxx ll cccc dd}.any? { |x| str.include?(x) }
str.tr!("ivxlcdm", "0123456") # translate into numbers
level, last, deviated, ret , 0, false, 0
table 1,5,10,50,100,500,1000] # the translation table
str.each_char do |char|
num har.to_i
if num > level # means a deviation
raise SyntaxError, "Not a roman numeral" if deviated or
not # no double deviation
%w{01 02 23 24 45 46}.include?("#{last}#{num}") #
only allowed deviations
ret - able[last]*2 # remedy deviation
level ast-1 # don't allow IXI or IXV etc.
deviated rue
else
deviated alse
level um # don't allow MLM etc.
end
ret + able[num]
last um
end
ret
end
end
fulfills all your examples, but i dunno if it's correct. would be great if
someone
could test this (let alone improve it).
What it checks for:
* only [ivxlcdm] allowed
* ixc may each only occur max. 3 times in a row
* vld may each only occur max once in a row
* when dropping to a certain level, only the following sequences may rise
above that level: cm cd xc xl ix iv
* and not twice in a row, so ixc is not legal
* and after that, the level drops to the smaller char, so ixivi is not
legal
...and then you try to evaluate the string value XD (for example), it
> will convert this string to 510. This should not happen; XD is not a
> legal roman numeral, DX would be 510, and CDXC would be 490. The
> problem seems to be that in roman to arabic numeral conversion, the
> solutions just add the raw values together. This means that converters
> using this kind of conversion will accept any combination of roman
> numeral values from the table above...regardless of order.
>
> A crazier example:
>
> If you evaluate XIV, you get 14, by finding X and then IV in the table
> above and then adding their corresponding values together.
>
> If you put in IXIVI, it will *also* evaluate to 14 by adding IX + IV + I
> and accept it as a valid roman numeral.
>
>
--00504502d48e72e6750473dfb830--