Skip to content

Instantly share code, notes, and snippets.

@gauravsaini23
Last active December 22, 2015 15:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gauravsaini23/6494806 to your computer and use it in GitHub Desktop.
Save gauravsaini23/6494806 to your computer and use it in GitHub Desktop.
class RomanNumber
ROMAN_NUMBER = { I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000 }
def initialize(roman)
@roman = roman
fail(NotValidRomanNumber, 'String is not a valid roman number') unless valid?
@syms = @roman.split('').collect(&:to_sym)
end
def valid?
@roman =~ /^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/
end
def to_integer
total = 0
@syms.each_with_index do |sym, index|
@current_sym = sym
@index = index
if sym != @syms.last && next_number_greater?
total -= convert_to_integer
else
total += convert_to_integer
end
end
total
end
private
#converts the single roman symbol to integer
def convert_to_integer(sym = @current_sym)
ROMAN_NUMBER[sym]
end
def next_number_greater?(index=@index)
@grtr = convert_to_integer < convert_to_integer(next_symbol(index))
end
def next_symbol(index)
@syms[index + 1]
end
end
class NotValidRomanNumber < StandardError; end
require './roman_number'
require 'test/unit'
class TestRoman < Test::Unit::TestCase
def test_single_roman_number
assert_equal RomanNumber.new('I').to_integer, 1
assert_equal RomanNumber.new('V').to_integer, 5
assert_equal RomanNumber.new('X').to_integer, 10
assert_equal RomanNumber.new('L').to_integer, 50
assert_equal RomanNumber.new('C').to_integer, 100
assert_equal RomanNumber.new('D').to_integer, 500
assert_equal RomanNumber.new('M').to_integer, 1000
end
def test_multiple_identical
assert_equal RomanNumber.new('II').to_integer, 2
assert_equal RomanNumber.new('III').to_integer, 3
assert_equal RomanNumber.new('XX').to_integer, 20
assert_equal RomanNumber.new('CC').to_integer, 200
assert_equal RomanNumber.new('MMM').to_integer, 3000
end
def test_multiple_different
assert_equal RomanNumber.new('IV').to_integer, 4
assert_equal RomanNumber.new('XXXI').to_integer, 31
assert_equal RomanNumber.new('MCMXCVIII').to_integer, 1998
assert_equal RomanNumber.new('MMMDCCCLXXXVIII').to_integer, 3888
end
def test_invalid
assert_raise(NotValidRomanNumber, 'String is not a valid roman number') do
RomanNumber.new('232').to_integer
end
assert_raise(NotValidRomanNumber, 'String is not a valid roman number') do
RomanNumber.new('KJHDHKDH').to_integer
end
assert_raise(NotValidRomanNumber, 'String is not a valid roman number') do
RomanNumber.new('MMMMMM').to_integer
end
assert_raise(NotValidRomanNumber, 'String is not a valid roman number') do
RomanNumber.new('IIIII').to_integer
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment