Module: RomanNumeralEvaluator

Defined in:
lib/version.rb,
lib/roman_numeral_evaluator.rb

Constant Summary collapse

VERSION =
"0.0.3"
VALID_NUMERICAL_PATTERN =
/(M{1,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})|M{0,4}(CM|C?D|D?C{1,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})|M{0,4}(CM|CD|D?C{0,3})(XC|X?L|L?X{1,3})(IX|IV|V?I{0,3})|M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|I?V|V?I{1,3}))/
DIGITS =
{
  1    => 'I',
  4    => 'IV',
  5    => 'V',
  9    => 'IX',
  10   => 'X',
  40   => 'XL',
  50   => 'L',
  90   => 'XC',
  100  => 'C',
  400  => 'CD',
  500  => 'D',
  900  => 'CM',
  1000 => 'M'
}

Class Method Summary collapse

Class Method Details

.is_roman?(value) ⇒ Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/roman_numeral_evaluator.rb', line 63

def self.is_roman?(value)
  value.match(VALID_NUMERICAL_PATTERN)
end

.solve(problem) ⇒ Object

problem is a string representing a Roman math problem, such as ‘I + I’. Returns roman result, as a string, such as ‘II’



8
9
10
# File 'lib/roman_numeral_evaluator.rb', line 8

def self.solve(problem)
  to_roman(solve_as_integer(problem))
end

.solve_as_integer(problem) ⇒ Object

Takes ‘I + I’, returns 2. Recursively replaces a first Roman numeral in a string with decimal.



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/roman_numeral_evaluator.rb', line 13

def self.solve_as_integer(problem)
  # replaces strings in problem with corresponding integers, eval result
   
  if problem.match(VALID_NUMERICAL_PATTERN)
    # There are roman characters.  Replace the first word, solve the result.
    solve_as_integer(problem.sub(VALID_NUMERICAL_PATTERN){ |n| to_decimal(n) })
  else
    # Base Case:  There are no roman characters in problem.  We're done. Return the evaluated result.
    eval(problem)
  end
end

.to_decimal(value) ⇒ Object



52
53
54
55
56
57
58
59
60
61
# File 'lib/roman_numeral_evaluator.rb', line 52

def self.to_decimal(value)
  result = 0
  DIGITS.values.reverse.each do |roman|
    while value.start_with? roman
      value = value.slice(roman.length, value.length)
      result += DIGITS.key roman
    end
  end
  result
end

.to_roman(value) ⇒ Object



41
42
43
44
45
46
47
48
49
50
# File 'lib/roman_numeral_evaluator.rb', line 41

def self.to_roman(value)
  result = ''
  DIGITS.keys.reverse.each do |decimal|
    while value >= decimal
      value -= decimal
      result = result << DIGITS[decimal]
    end
  end
  result
end