On Fri, 4 Mar 2005 22:53:20 +0900, Ruby Quiz <james / grayproductions.net> 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öäer
http://ruby.brian-schroeder.de/