Class: RomanNumeral
- Includes:
- Comparable
- Defined in:
- lib/roman.rb
Overview
Work with Roman numerals just like normal Integers.
Constant Summary collapse
- MAX =
The largest integer representable as a roman numerable by this module.
3999
- REGEXP =
Taken 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
- ROMAN_VALUES_ASSOC =
[ ["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] ]
- ROMAN_VALUES =
ROMAN_VALUES_ASSOC.inject({}){ |h,(r,a)| h[r] = a; h }
Class Method Summary collapse
- .from_integer(int) ⇒ Object
-
.is_roman_numeral?(string) ⇒ Boolean
Returns true if
string
is a roman numeral. - .to_integer(roman) ⇒ Object
Instance Method Summary collapse
-
#&(o) ⇒ Object
bit operators.
- #*(o) ⇒ Object
- #**(o) ⇒ Object
- #+(o) ⇒ Object
- #+@ ⇒ Object
- #-(o) ⇒ Object
- #-@ ⇒ Object
- #/(o) ⇒ Object
- #<<(o) ⇒ Object
- #<=>(o) ⇒ Object
- #==(num) ⇒ Object
- #>>(o) ⇒ Object
- #between?(a, b) ⇒ Boolean
- #coerce(o) ⇒ Object
- #eql?(num) ⇒ Boolean
- #even? ⇒ Boolean
-
#freeze ⇒ Object
Freeze.
-
#hash ⇒ Object
hash code calculation.
-
#initialize(val) ⇒ RomanNumeral
constructor
Create a new instance from an Integer, String or other RomanNumeral.
- #integer? ⇒ Boolean
- #nonzero? ⇒ Boolean
- #odd? ⇒ Boolean
- #real? ⇒ Boolean
- #to_arabic ⇒ Object
- #to_i ⇒ Object
- #to_int ⇒ Object
- #to_num ⇒ Object
- #to_roman ⇒ Object
- #to_s ⇒ Object
-
#zero? ⇒ Boolean
various tests that Fixnum also has.
- #|(o) ⇒ Object
Constructor Details
#initialize(val) ⇒ RomanNumeral
Create a new instance from an Integer, String or other RomanNumeral.
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/roman.rb', line 66 def initialize(val) case val when String @i = self.class.to_integer(val) @s = val.frozen? ? val : val.dup.freeze when Numeric @i = val.to_i else raise ArgumentError, 'Cannot convert %p' % val end end |
Class Method Details
.from_integer(int) ⇒ Object
34 35 36 37 38 39 40 41 |
# File 'lib/roman.rb', line 34 def self.from_integer(int) #return nil if integer > MAX return "-#{(-int).roman}" if int < 0 return "" if int == 0 ROMAN_VALUES_ASSOC.each do |(i, v)| return(i + from_integer(int-v)) if v <= int end end |
.is_roman_numeral?(string) ⇒ Boolean
Returns true if string
is a roman numeral.
59 60 61 |
# File 'lib/roman.rb', line 59 def self.is_roman_numeral?(string) REGEXP =~ string end |
.to_integer(roman) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/roman.rb', line 44 def self.to_integer(roman) #return nil unless roman_string.is_roman_numeral? last = roman[-1,1].upcase roman.reverse.split('').inject(0) do |result, c| c = c.upcase if ROMAN_VALUES[c] < ROMAN_VALUES[last] result -= ROMAN_VALUES[c] else last = c result += ROMAN_VALUES[c] end end end |
Instance Method Details
#&(o) ⇒ Object
bit operators
229 230 231 |
# File 'lib/roman.rb', line 229 def &(o) self.class.new(@i & o.to_int) end |
#*(o) ⇒ Object
191 192 193 194 195 196 197 198 |
# File 'lib/roman.rb', line 191 def *(o) if Numeric === o self.class.new(@i * o.to_num) else a, b = o.coerce(self) a * b end end |
#**(o) ⇒ Object
210 211 212 213 214 215 216 217 |
# File 'lib/roman.rb', line 210 def **(o) if Numeric === o self.class.new(@i / o.to_num) else a, b = o.coerce(self) a / b end end |
#+(o) ⇒ Object
171 172 173 174 175 176 177 178 |
# File 'lib/roman.rb', line 171 def +(o) if Numeric === o self.class.new(@i + o.to_num) else a, b = o.coerce(self) a + b end end |
#+@ ⇒ Object
162 163 164 |
# File 'lib/roman.rb', line 162 def +@ self end |
#-(o) ⇒ Object
181 182 183 184 185 186 187 188 |
# File 'lib/roman.rb', line 181 def -(o) if Numeric === o self.class.new(@i - o.to_num) else a, b = o.coerce(self) a - b end end |
#-@ ⇒ Object
166 167 168 |
# File 'lib/roman.rb', line 166 def -@ self.class.new(-@i) end |
#/(o) ⇒ Object
201 202 203 204 205 206 207 208 |
# File 'lib/roman.rb', line 201 def /(o) if Numeric === o self.class.new(@i / o.to_num) else a, b = o.coerce(self) a / b end end |
#<<(o) ⇒ Object
219 220 221 |
# File 'lib/roman.rb', line 219 def <<(o) self.class.new(@i << o.to_int) end |
#<=>(o) ⇒ Object
122 123 124 125 126 127 128 129 130 |
# File 'lib/roman.rb', line 122 def <=>(o) case o when Numeric @i <=> o.to_num else a, b = o.coerce(self) a <=> b end rescue nil end |
#==(num) ⇒ Object
112 113 114 |
# File 'lib/roman.rb', line 112 def ==(num) @i == num.to_num end |
#>>(o) ⇒ Object
223 224 225 |
# File 'lib/roman.rb', line 223 def >>(o) self.class.new(@i >> o.to_int) end |
#between?(a, b) ⇒ Boolean
150 151 152 |
# File 'lib/roman.rb', line 150 def between?(a, b) @i.between? a, b end |
#coerce(o) ⇒ Object
117 118 119 |
# File 'lib/roman.rb', line 117 def coerce(o) [self.class.new(o.to_int), self] end |
#eql?(num) ⇒ Boolean
107 108 109 |
# File 'lib/roman.rb', line 107 def eql?(num) self.class.equal?(num.class) && @i == num.to_i end |
#even? ⇒ Boolean
146 147 148 |
# File 'lib/roman.rb', line 146 def even? @i.even? end |
#freeze ⇒ Object
Freeze
238 239 240 241 |
# File 'lib/roman.rb', line 238 def freeze to_s super end |
#hash ⇒ Object
hash code calculation
80 81 82 |
# File 'lib/roman.rb', line 80 def hash @i.hash end |
#integer? ⇒ Boolean
154 155 156 |
# File 'lib/roman.rb', line 154 def integer? true end |
#nonzero? ⇒ Boolean
138 139 140 |
# File 'lib/roman.rb', line 138 def nonzero? @i.nonzero? end |
#odd? ⇒ Boolean
142 143 144 |
# File 'lib/roman.rb', line 142 def odd? @i.odd? end |
#real? ⇒ Boolean
158 159 160 |
# File 'lib/roman.rb', line 158 def real? true end |
#to_arabic ⇒ Object
99 |
# File 'lib/roman.rb', line 99 def to_arabic ; @i ; end |
#to_i ⇒ Object
93 |
# File 'lib/roman.rb', line 93 def to_i ; @i ; end |
#to_int ⇒ Object
96 |
# File 'lib/roman.rb', line 96 def to_int ; @i ; end |
#to_num ⇒ Object
90 |
# File 'lib/roman.rb', line 90 def to_num ; @i ; end |
#to_roman ⇒ Object
102 103 104 |
# File 'lib/roman.rb', line 102 def to_roman self end |
#to_s ⇒ Object
85 86 87 |
# File 'lib/roman.rb', line 85 def to_s @s ||= self.class.from_integer(@i) end |
#zero? ⇒ Boolean
various tests that Fixnum also has
134 135 136 |
# File 'lib/roman.rb', line 134 def zero? @i.zero? end |
#|(o) ⇒ Object
233 234 235 |
# File 'lib/roman.rb', line 233 def |(o) self.class.new(@i | o.to_int) end |