O'Reilly logo

Ruby Cookbook by Leonard Richardson, Lucas Carlson

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

2.14. Doing Math with Roman Numbers

Problem

You want to convert between Arabic and Roman numbers, or do arithmetic with Roman numbers and get Roman numbers as your result.

Solution

The simplest way to define a Roman class that acts like Fixnum is to have its instances delegate most of their method calls to a real Fixnum (as seen in the previous recipe, Recipe 2.13). First we'll implement a container for the Fixnum delegate, and methods to convert between Roman and Arabic numbers:

	class Roman
	  # These arrays map all distinct substrings of Roman numbers
	  # to their Arabic equivalents, and vice versa.
	  @@roman_to_arabic = [['M', 1000], ['CM', 900], ['D', 500], ['CD', 400],
	    ['C', 100], ['XC', 90], ['L', 50], ['XL', 40], ['X', 10], ['IX', 9],
	    ['V', 5], ['IV', 4], ['I', 1]]
	  @@arabic_to_roman = @@roman_to_arabic.collect { |x| x.reverse }.reverse

	  # The Roman symbol for 5000 (a V with a bar over it) is not in
	  # ASCII nor Unicode, so we won't represent numbers larger than 3999.
	  MAX = 3999

	  def initialize(number)
	    if number.respond_to? :to_str
	      @value = Roman.to_arabic(number)
	    else
	      Roman.assert_within_range(number)
	      @value = number
	    end
	  end

	  # Raise an exception if a number is too large or small to be represented
	  # as a 
Roman number.
	  def  Roman.assert_within_range(number) unless number.between?(1, MAX) msg = "#{number} can't be represented as a Roman number." raise RangeError.new(msg) end end #Find the Fixnum value of a string containing a Roman number. def Roman.to_arabic(s) value = s if s.respond_to? ...

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required