Module: English::RomanNumerals

Defined in:
lib/gems/english-0.3.1/lib/english/roman.rb

Overview

Contains methods to convert integers to roman numeral strings and vice-versa.

Constant Summary collapse

MAX =

The largest integer representable as a roman numerable by this module.

3999
REGEXP =

Stolen from O’Reilly’s Perl Cookbook 6.23. Regular Expression Grabbag.

/^M*(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$/i
SYMBOLS =
[  "M", "D", "C", "L", "X", "V", "I" ]
NUMBERS =
[ 1000, 500, 100,  50,  10,   5,   1 ]
TABLE =

Maps roman numeral digits to their integer values.

{
  'I' => 1,
  'V' => 5,
  'X' => 10,
  'L' => 50,
  'C' => 100,
  'D' => 500,
  'M' => 1000,
}
PAIR_SYMBOLS =
[ "CM", "CD", "XC", "XL", "IX", "IV", "I" ]
PAIR_NUMBERS =
[ 900,  400,    90,   40,    9,    4,   1 ]
PAIR_TABLE =

{

  'CM' => 900,
  'CD' => 400,
  'XC' => 90,
  'XL' => 40,
  'IX' => 9,
  'IV' => 4
}
LOOKUP =
TABLE.invert.merge(PAIR_TABLE.invert)

Class Method Summary collapse

Class Method Details

.from_integer(integer) ⇒ Object Also known as: roman

Converts integer to a roman numeral.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/gems/english-0.3.1/lib/english/roman.rb', line 73

def from_integer(integer)
  return nil if integer < 0 || integer > MAX

  r = integer  # remainder
  y = ''       # result

  NUMBERS.each do |n|
    while r >= n
      r -= n
      y += LOOKUP[n]
    end
    break if r <= 0
  end

  return y
end

.is_roman_numeral?(string) ⇒ Boolean

Returns true iif string is a roman numeral.

Returns:

  • (Boolean)


120
121
122
# File 'lib/gems/english-0.3.1/lib/english/roman.rb', line 120

def is_roman_numeral?(string)
  REGEXP =~ string
end

.to_integer(roman_string) ⇒ Object Also known as: arabic

Converts roman_string, a roman numeral, to an integer



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/gems/english-0.3.1/lib/english/roman.rb', line 94

def to_integer(roman_string)
  return nil unless roman_string.is_roman_numeral?

  l = nil  # last
  i = 0    # integer result

  c = roman_string.to_s.upcase.split(//).reverse

  c.each do |d|
    if v = TABLE[d]
      if l && l > v
        i -= v
      else
        i += v
      end
      l = v
    end
  end

  return i
end