roman-numeral 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.
- checksums.yaml +7 -0
- data/README.md +54 -0
- data/Rakefile +6 -0
- data/bin/roman_numerals +4 -0
- data/lib/roman-numeral.rb +79 -0
- data/roman_numerals.gemspec +19 -0
- data/spec/roman_numerals_spec.rb +140 -0
- metadata +94 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f840c06e27e38aabf5ef2e833c6589c24955fad3
|
4
|
+
data.tar.gz: 4d1d9d584d3733bd8b32b092746ef78b56329e5f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 24892f4443f85a242c3073c4ee1d0427f79c0782d46db8ff808f9b77d503d37a36202802bc741eabeb158685d654b22f3eac9b8706b40cb48adb62f2a271f7a0
|
7
|
+
data.tar.gz: d309ad7de6114966aec3e5cf3e8798970799ecc32ce50695bb37df9d03abf13086cb7203c178758f5ac8de97f6ad015900e7270116d5e8205a54a873468dc310
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# roman-numeral
|
2
|
+
|
3
|
+
Convert roman numeral to decimal number or viceversa.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
To use the roman numerals gem, you need to add this line to your Gemfile
|
8
|
+
|
9
|
+
```
|
10
|
+
gem 'roman-numeral'
|
11
|
+
```
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
```
|
15
|
+
$ bundle
|
16
|
+
```
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
```
|
20
|
+
$ gem install roman-numeral
|
21
|
+
```
|
22
|
+
|
23
|
+
##Usage
|
24
|
+
In *irb* console:
|
25
|
+
|
26
|
+
Convert roman numeral to decimal number
|
27
|
+
```
|
28
|
+
>> require 'roman-numeral'
|
29
|
+
|
30
|
+
>> r = RomanNumeral.new("IV")
|
31
|
+
>> r.to_decimal
|
32
|
+
=> 4
|
33
|
+
|
34
|
+
>> r = RomanNumeral.new("IVI")
|
35
|
+
>> r.to_decimal
|
36
|
+
=> "Invalid numeral IVI"
|
37
|
+
|
38
|
+
```
|
39
|
+
Convert decimal number to roman numeral
|
40
|
+
```
|
41
|
+
>> d = RomanNumeral.new(17)
|
42
|
+
>> d.to_roman
|
43
|
+
=> "XVII"
|
44
|
+
|
45
|
+
>> r = RomanNumeral.new(10.23)
|
46
|
+
>> r.to_roman
|
47
|
+
=> "Invalid numeral 10.23"
|
48
|
+
```
|
49
|
+
|
50
|
+
###Basic working principles of roman-rumeral
|
51
|
+
In order to convert roman numeral to decimal nuber, it works like a **State Machine**.
|
52
|
+
|
53
|
+
|
54
|
+
|
data/Rakefile
ADDED
data/bin/roman_numerals
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
class RomanNumeral
|
2
|
+
attr_reader :numeral
|
3
|
+
|
4
|
+
def initialize( numeral )
|
5
|
+
@numeral = numeral
|
6
|
+
end
|
7
|
+
|
8
|
+
def numerals_map
|
9
|
+
{
|
10
|
+
1 => 'I',
|
11
|
+
4 => 'IV',
|
12
|
+
5 => 'V',
|
13
|
+
9 => 'IX',
|
14
|
+
10 => 'X',
|
15
|
+
40 => 'XL',
|
16
|
+
50 => 'L',
|
17
|
+
90 => 'XC',
|
18
|
+
100 => 'C',
|
19
|
+
400 => 'CD',
|
20
|
+
500 => 'D',
|
21
|
+
900 => 'CM',
|
22
|
+
1000 => 'M'
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid_roman?
|
27
|
+
#Will considered as valid input if input string contains roman numeral in correct order
|
28
|
+
!!(numeral.to_s.upcase =~ /^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/)
|
29
|
+
end
|
30
|
+
|
31
|
+
def valid_decimal?
|
32
|
+
!!(numeral.to_s =~ /^\d+$/)
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_decimal
|
36
|
+
if valid_roman?
|
37
|
+
decimal = convert_to
|
38
|
+
elsif valid_decimal?
|
39
|
+
numeral
|
40
|
+
else
|
41
|
+
"Invalid numeral #{numeral}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_roman
|
46
|
+
if valid_decimal?
|
47
|
+
roman = convert_from
|
48
|
+
elsif valid_roman?
|
49
|
+
numeral
|
50
|
+
else
|
51
|
+
"Invalid numeral #{numeral}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def convert_to
|
56
|
+
value = 0
|
57
|
+
roman_symbols = numeral.to_s.upcase
|
58
|
+
numerals_map.values.reverse.each do |symbol|
|
59
|
+
while roman_symbols.start_with? ( symbol )
|
60
|
+
roman_symbols = roman_symbols.slice(symbol.length, roman_symbols.length)
|
61
|
+
value += numerals_map.key( symbol )
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
value
|
66
|
+
end
|
67
|
+
|
68
|
+
def convert_from
|
69
|
+
value = ''
|
70
|
+
decimal_number = numeral.to_i
|
71
|
+
numerals_map.keys.reverse.each do |decimal|
|
72
|
+
while decimal_number >= decimal
|
73
|
+
decimal_number -= decimal
|
74
|
+
value += numerals_map[decimal]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
value
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Gem::Specification.new do |spec|
|
2
|
+
spec.name = "roman-numeral"
|
3
|
+
spec.version = "0.0.1"
|
4
|
+
spec.authors = ["Suvankar Satpati"]
|
5
|
+
spec.email = ["suvankar.17@gmail.com"]
|
6
|
+
spec.description = %q{Roman numeral converter}
|
7
|
+
spec.summary = %q{Convert roman numeral to decimal and viceversa}
|
8
|
+
spec.homepage = "https://github.com/suvankars/gems/tree/master/roman_numerals"
|
9
|
+
spec.license = "Suvankar"
|
10
|
+
|
11
|
+
spec.files = `git ls-files`.split($/)
|
12
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
13
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
14
|
+
spec.require_paths = ["lib"]
|
15
|
+
|
16
|
+
spec.add_development_dependency "bundler", "~> 1.3.5"
|
17
|
+
spec.add_development_dependency "rspec"
|
18
|
+
spec.add_development_dependency "rake"
|
19
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'roman-numeral'
|
5
|
+
|
6
|
+
describe RomanNumeral do
|
7
|
+
base_digits = {
|
8
|
+
1 => 'I',
|
9
|
+
4 => 'IV',
|
10
|
+
5 => 'V',
|
11
|
+
9 => 'IX',
|
12
|
+
10 => 'X',
|
13
|
+
40 => 'XL',
|
14
|
+
50 => 'L',
|
15
|
+
90 => 'XC',
|
16
|
+
100 => 'C',
|
17
|
+
400 => 'CD',
|
18
|
+
500 => 'D',
|
19
|
+
900 => 'CM',
|
20
|
+
1000 => 'M'
|
21
|
+
}
|
22
|
+
|
23
|
+
describe ".valid_roman?" do
|
24
|
+
it "should find wheather an input belongs to 7 valid roman numeral" do
|
25
|
+
inputs = [ "I", "V", "M", "D", "L"]
|
26
|
+
inputs.each do | roman |
|
27
|
+
numeral = RomanNumeral.new( roman )
|
28
|
+
numeral.valid_roman?.should == true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should find invalid roman numerals" do
|
33
|
+
invalid_inputs = [ "S", "A", "T", "P", "A", "T", "E"]
|
34
|
+
invalid_inputs.each do | roman |
|
35
|
+
numeral = RomanNumeral.new( roman )
|
36
|
+
numeral.valid_roman?.should == false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should check valid combination of roman numerals" do
|
41
|
+
numerals = [ "III", "IV", "VIII"]
|
42
|
+
numerals.each do | roman |
|
43
|
+
numeral = RomanNumeral.new( roman )
|
44
|
+
numeral.valid_roman?.should == true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should check invalid roman numerals combination" do
|
49
|
+
numerals = [ "DD", "LL", "VVV", "DLLD"]
|
50
|
+
numerals.each do | roman |
|
51
|
+
numeral = RomanNumeral.new( roman )
|
52
|
+
numeral.valid_roman?.should == false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe ".valid_decimal?" do
|
58
|
+
it "should find wheather an input is valid decimal number" do
|
59
|
+
decimal_number = [ 1, 4, 8, 123]
|
60
|
+
decimal_number.each do | number |
|
61
|
+
numeral = RomanNumeral.new( number.to_s )
|
62
|
+
numeral.valid_decimal?.should == true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
decimal_number = [ 1.12, -8]
|
67
|
+
decimal_number.each do | number |
|
68
|
+
it "should find wheather an input number: #{number.to_s} is INVALID decimal number" do
|
69
|
+
numeral = RomanNumeral.new( number.to_s )
|
70
|
+
numeral.valid_decimal?.should == false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
describe ".to_decimal" do
|
77
|
+
base_digits.each do |decimal, roman|
|
78
|
+
it "should convert the roman numeral #{roman} to the decimal value #{decimal}" do
|
79
|
+
numeral = RomanNumeral.new( roman )
|
80
|
+
numeral.to_decimal.should == decimal
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
numerals = { 'MCMXLIV' => 1944,
|
85
|
+
'IX' => 9,
|
86
|
+
'DLIX' => 559,
|
87
|
+
'XI' => 11,
|
88
|
+
'xvii' => 17
|
89
|
+
}
|
90
|
+
|
91
|
+
numerals.each do |roman, decimal|
|
92
|
+
it "should convert the roman numeral #{roman} to the decimal value #{decimal}" do
|
93
|
+
numeral = RomanNumeral.new( roman )
|
94
|
+
numeral.to_decimal.should == decimal
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
describe ".to_roman" do
|
101
|
+
base_digits.each do |decimal, roman|
|
102
|
+
it "should convert the int decimal value #{decimal} to the roman numeral #{roman}" do
|
103
|
+
numeral = RomanNumeral.new( decimal )
|
104
|
+
numeral.to_roman.should == roman
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should convert string decimal value to roman numeral" do
|
109
|
+
numeral = RomanNumeral.new( "4" )
|
110
|
+
numeral.to_roman.should == "IV"
|
111
|
+
end
|
112
|
+
|
113
|
+
numerals = ['VX', 'LL', 'IIII', 'VVLDD', 'IDD']
|
114
|
+
numerals.each do |roman|
|
115
|
+
it "should NOT convert the roman numeral #{roman} to the decimal value " do
|
116
|
+
numeral = RomanNumeral.new( roman )
|
117
|
+
numeral.to_decimal.should == "Invalid numeral #{roman}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "Conversion from Roman to Decimal and viceversa" do
|
123
|
+
it "should convert roman to roman" do
|
124
|
+
numeral = RomanNumeral.new( "IV" )
|
125
|
+
numeral.to_roman.should == "IV"
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should convert decimal to decimal" do
|
129
|
+
numeral = RomanNumeral.new( 4 )
|
130
|
+
numeral.to_decimal.should == 4
|
131
|
+
numeral = RomanNumeral.new( "4")
|
132
|
+
numeral.to_decimal.should == "4"
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should not convert to any value" do
|
136
|
+
numeral = RomanNumeral.new( "4IV" )
|
137
|
+
numeral.to_roman.should == "Invalid numeral 4IV"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: roman-numeral
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Suvankar Satpati
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.3.5
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.3.5
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Roman numeral converter
|
56
|
+
email:
|
57
|
+
- suvankar.17@gmail.com
|
58
|
+
executables:
|
59
|
+
- roman_numerals
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- README.md
|
64
|
+
- Rakefile
|
65
|
+
- bin/roman_numerals
|
66
|
+
- lib/roman-numeral.rb
|
67
|
+
- roman_numerals.gemspec
|
68
|
+
- spec/roman_numerals_spec.rb
|
69
|
+
homepage: https://github.com/suvankars/gems/tree/master/roman_numerals
|
70
|
+
licenses:
|
71
|
+
- Suvankar
|
72
|
+
metadata: {}
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
requirements: []
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 2.0.3
|
90
|
+
signing_key:
|
91
|
+
specification_version: 4
|
92
|
+
summary: Convert roman numeral to decimal and viceversa
|
93
|
+
test_files:
|
94
|
+
- spec/roman_numerals_spec.rb
|