From: "Brian Schröder" Date: 2005-03-07T17:19:26+09:00 Subject: Re: [Solution] [QUIZ] Roman Numerals (#22) On Fri, 4 Mar 2005 22:53:20 +0900, Ruby Quiz wrote: > [Snipped Quiz Description] Hello Group, I attach my solution here, but as always the full color version can be found at: http://ruby.brian-schroeder.de/quiz/roman/ The solution: -------------- I chose to change the Integer class for this. class Integer First I set up two constants. The first is needed for conversion from integer to roman, the second for conversion from roman to integer. @@roman_values_assoc = %w(I IV V IX X XL L XC C CD D CM M).zip([1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000]).reverse @@roman_values = @@roman_values_assoc.inject({}) { |h, (r,a)| h[r] = a; h } Then we will come to the core. I implemented integer to roman as a recursive process, where in each iteration the biggest possible part of the number is matched by a roman number, then the rest is done the same way. Negative roman numbers did not exist, but why not simply prefix a roman number with a minus sign? def roman return "-#{(-self).roman}" if self < 0 return "" if self == 0 @@roman_values_assoc.each do | (i, v) | return(i+(self-v).roman) if v <= self end end Converting romans to integer is done by reading the roman number from right to left, detecting if we are in the subtraction or the addition case and summing up the results. Nothing complicated. def Integer.roman(roman) last = roman[-1,1] roman.reverse.split('').inject(0) { | result, c | if @@roman_values[c] < @@roman_values[last] result -= @@roman_values[c] else last = c result += @@roman_values[c] end } end Thats all there is to roman numbers. end cheers, Brian -- Brian Schr�der http://ruby.brian-schroeder.de/