roman_numeral_evaluator 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -0
- data/Gemfile.lock +24 -0
- data/Rakefile +2 -0
- data/lib/LICENSE +22 -0
- data/lib/roman_numeral_evaluator.rb +69 -0
- data/lib/string.rb +25 -0
- data/lib/version.rb +3 -0
- data/readme.md +41 -0
- data/roman_numeral_evaluator.gemspec +19 -0
- data/spec/roman_numeral_evaluator_spec.rb +33 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/string_spec.rb +29 -0
- metadata +77 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
roman_numeral_evaluator (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.1.3)
|
10
|
+
rspec (2.12.0)
|
11
|
+
rspec-core (~> 2.12.0)
|
12
|
+
rspec-expectations (~> 2.12.0)
|
13
|
+
rspec-mocks (~> 2.12.0)
|
14
|
+
rspec-core (2.12.2)
|
15
|
+
rspec-expectations (2.12.1)
|
16
|
+
diff-lcs (~> 1.1.3)
|
17
|
+
rspec-mocks (2.12.2)
|
18
|
+
|
19
|
+
PLATFORMS
|
20
|
+
ruby
|
21
|
+
|
22
|
+
DEPENDENCIES
|
23
|
+
roman_numeral_evaluator!
|
24
|
+
rspec
|
data/Rakefile
ADDED
data/lib/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Travis Sheppard
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative 'version'
|
2
|
+
require_relative 'string'
|
3
|
+
|
4
|
+
module RomanNumeralEvaluator
|
5
|
+
|
6
|
+
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}))/
|
7
|
+
|
8
|
+
# problem is a string representing a Roman math problem, such as 'I + I'. Returns roman result, as a string, such as 'II'
|
9
|
+
def self.solve(problem)
|
10
|
+
to_roman(solve_as_integer(problem.upcase))
|
11
|
+
end
|
12
|
+
|
13
|
+
# Takes 'I + I', returns 2. Recursively replaces a first Roman numeral in a string with decimal.
|
14
|
+
def self.solve_as_integer(problem)
|
15
|
+
# replaces strings in problem with corresponding integers, eval result
|
16
|
+
|
17
|
+
if problem.match(VALID_NUMERICAL_PATTERN)
|
18
|
+
# There are roman characters. Replace the first word, solve the result.
|
19
|
+
solve_as_integer(problem.sub(VALID_NUMERICAL_PATTERN){ |n| to_decimal(n) })
|
20
|
+
else
|
21
|
+
# Base Case: There are no roman characters in problem. We're done. Return the evaluated result.
|
22
|
+
eval(problem)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
DIGITS = {
|
27
|
+
1 => 'I',
|
28
|
+
4 => 'IV',
|
29
|
+
5 => 'V',
|
30
|
+
9 => 'IX',
|
31
|
+
10 => 'X',
|
32
|
+
40 => 'XL',
|
33
|
+
50 => 'L',
|
34
|
+
90 => 'XC',
|
35
|
+
100 => 'C',
|
36
|
+
400 => 'CD',
|
37
|
+
500 => 'D',
|
38
|
+
900 => 'CM',
|
39
|
+
1000 => 'M'
|
40
|
+
}
|
41
|
+
|
42
|
+
def self.to_roman(value)
|
43
|
+
result = ''
|
44
|
+
DIGITS.keys.reverse.each do |decimal|
|
45
|
+
while value >= decimal
|
46
|
+
value -= decimal
|
47
|
+
result = result << DIGITS[decimal]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
result
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.to_decimal(value)
|
54
|
+
value.upcase!
|
55
|
+
result = 0
|
56
|
+
DIGITS.values.reverse.each do |roman|
|
57
|
+
while value.start_with? roman
|
58
|
+
value = value.slice(roman.length, value.length)
|
59
|
+
result += DIGITS.key roman
|
60
|
+
end
|
61
|
+
end
|
62
|
+
result
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.is_roman?(value)
|
66
|
+
value.match(VALID_NUMERICAL_PATTERN)
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/lib/string.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
def +(a)
|
4
|
+
if RomanNumeralEvaluator.is_roman?(self) || RomanNumeralEvaluator.is_roman?(a)
|
5
|
+
number = RomanNumeralEvaluator.to_decimal(self)
|
6
|
+
other = RomanNumeralEvaluator.to_decimal(a)
|
7
|
+
RomanNumeralEvaluator.to_roman(number + other)
|
8
|
+
else
|
9
|
+
self << a
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def -(a)
|
14
|
+
RomanNumeralEvaluator.solve("#{self} - #{a}")
|
15
|
+
end
|
16
|
+
|
17
|
+
def *(a)
|
18
|
+
RomanNumeralEvaluator.solve("#{self} * #{a}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def /(a)
|
22
|
+
RomanNumeralEvaluator.solve("#{self} / #{a}")
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/version.rb
ADDED
data/readme.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
## About
|
2
|
+
|
3
|
+
A Ruby gem that extends the String class to do math with Roman numerals, as well as handle Roman math problems as strings.
|
4
|
+
|
5
|
+
"V" + "V"
|
6
|
+
=> "X"
|
7
|
+
|
8
|
+
RomanNumeralEvaluator.solve("I + I")
|
9
|
+
=> "II"
|
10
|
+
|
11
|
+
## Install
|
12
|
+
|
13
|
+
In your gemfile
|
14
|
+
|
15
|
+
gem 'roman_numeral_evaluator'
|
16
|
+
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
Basic problem
|
21
|
+
|
22
|
+
RomanNumeralEvaluator.solve('I + I')
|
23
|
+
=> "II"
|
24
|
+
|
25
|
+
RomanNumeralEvaluator.solve('X - I')
|
26
|
+
=> "IX"
|
27
|
+
|
28
|
+
Solve as integer
|
29
|
+
|
30
|
+
RomanNumeralEvaluator.solve_as_integer('X - I')
|
31
|
+
=> 9
|
32
|
+
|
33
|
+
You can multiply!
|
34
|
+
|
35
|
+
RomanNumeralEvaluator.solve('X * X')
|
36
|
+
=> "C"
|
37
|
+
|
38
|
+
Mix Roman and Arabic
|
39
|
+
|
40
|
+
RomanNumeralEvaluator.solve('X * 10')
|
41
|
+
=> "C"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Travis Sheppard"]
|
6
|
+
gem.email = ["travissheppard.1988@gmail.com"]
|
7
|
+
gem.description = "A Ruby gem that extends the String class to do math with Roman numerals, as well as handle Roman math problems as strings."
|
8
|
+
gem.summary = ""
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "roman_numeral_evaluator"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = RomanNumeralEvaluator::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency(%q<rspec>)
|
19
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe RomanNumeralEvaluator do
|
4
|
+
|
5
|
+
it "should solve a Roman math problem, taking a string param, and returning the roman result" do
|
6
|
+
RomanNumeralEvaluator.solve('I + I').should eq('II')
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should add two roman numerals" do
|
10
|
+
RomanNumeralEvaluator.solve('I + IX').should eq('X')
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should subtract roman numerals" do
|
14
|
+
RomanNumeralEvaluator.solve('X - I').should eq('IX')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should add and subtract multiple numerals" do
|
18
|
+
RomanNumeralEvaluator.solve('X + V - III').should eq('XII')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should multiply numerals" do
|
22
|
+
RomanNumeralEvaluator.solve('X * X').should eq('C')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should divide roman numerals" do
|
26
|
+
RomanNumeralEvaluator.solve('C / X').should eq('X')
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should mix roman and arabic" do
|
30
|
+
RomanNumeralEvaluator.solve('X * 10').should eq("C")
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'Although not required, bundler is recommended for running the tests.'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require_relative '../lib/roman_numeral_evaluator'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
# some (optional) config here
|
12
|
+
end
|
data/spec/string_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
|
5
|
+
it "should add roman numerals" do
|
6
|
+
result = "V" + "V"
|
7
|
+
result.should eq("X")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should subtract roman numerals" do
|
11
|
+
result = "II" - "I"
|
12
|
+
result.should eq("I")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should multiply roman numerals" do
|
16
|
+
result = "II" * "II"
|
17
|
+
result.should eq("IV")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should divide roman numerals" do
|
21
|
+
result = "C" / "X"
|
22
|
+
result.should eq("X")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should add non roman strings normally" do
|
26
|
+
("a" + "b").should eq("ab")
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: roman_numeral_evaluator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Travis Sheppard
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: A Ruby gem that extends the String class to do math with Roman numerals,
|
31
|
+
as well as handle Roman math problems as strings.
|
32
|
+
email:
|
33
|
+
- travissheppard.1988@gmail.com
|
34
|
+
executables: []
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- Gemfile
|
39
|
+
- Gemfile.lock
|
40
|
+
- Rakefile
|
41
|
+
- lib/LICENSE
|
42
|
+
- lib/roman_numeral_evaluator.rb
|
43
|
+
- lib/string.rb
|
44
|
+
- lib/version.rb
|
45
|
+
- readme.md
|
46
|
+
- roman_numeral_evaluator.gemspec
|
47
|
+
- spec/roman_numeral_evaluator_spec.rb
|
48
|
+
- spec/spec_helper.rb
|
49
|
+
- spec/string_spec.rb
|
50
|
+
homepage: ''
|
51
|
+
licenses: []
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.8.24
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: ''
|
74
|
+
test_files:
|
75
|
+
- spec/roman_numeral_evaluator_spec.rb
|
76
|
+
- spec/spec_helper.rb
|
77
|
+
- spec/string_spec.rb
|