romans 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Kristian Mandrup
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ # Romans
2
+
3
+ Roman literals
4
+
5
+ ## Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ ## License
16
+
17
+ Author: +Dave Burt <dave at burt.id.au>+
18
+
19
+ +Fine print: Provided as is. Use at your own risk. Credit's appreciated if you use my code.+
@@ -0,0 +1,42 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "romans"
5
+ gem.summary = %Q{Roman numerals}
6
+ gem.description = %Q{Roman numerals library}
7
+ gem.email = "kmandrup@gmail.com"
8
+ gem.homepage = "http://github.com/kristianmandrup/romans"
9
+ gem.authors = ["Kristian Mandrup"]
10
+ gem.add_development_dependency "rspec", ">= 1.2.9"
11
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
12
+ end
13
+ Jeweler::GemcutterTasks.new
14
+ rescue LoadError
15
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
16
+ end
17
+
18
+ # require 'spec/rake/spectask'
19
+ # Spec::Rake::SpecTask.new(:spec) do |spec|
20
+ # spec.libs << 'lib' << 'spec'
21
+ # spec.spec_files = FileList['spec/**/*_spec.rb']
22
+ # end
23
+ #
24
+ # Spec::Rake::SpecTask.new(:rcov) do |spec|
25
+ # spec.libs << 'lib' << 'spec'
26
+ # spec.pattern = 'spec/**/*_spec.rb'
27
+ # spec.rcov = true
28
+ # end
29
+ #
30
+ # task :spec => :check_dependencies
31
+ #
32
+ # task :default => :spec
33
+ #
34
+ # require 'rake/rdoctask'
35
+ # Rake::RDocTask.new do |rdoc|
36
+ # version = File.exist?('VERSION') ? File.read('VERSION') : ""
37
+ #
38
+ # rdoc.rdoc_dir = 'rdoc'
39
+ # rdoc.title = "romans #{version}"
40
+ # rdoc.rdoc_files.include('README*')
41
+ # rdoc.rdoc_files.include('lib/**/*.rb')
42
+ # end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,184 @@
1
+ #
2
+ # Roman numerals
3
+ #
4
+ # Generates roman numerals from integers and vice-versa
5
+ #
6
+ # Author: Dave Burt <dave at burt.id.au>
7
+ #
8
+ # Fine print: Provided as is. Use at your own risk. Credit's appreciated if you use my code.
9
+ #
10
+
11
+
12
+ # http://media.pragprog.com/titles/fr_quiz/code/roman_numerals/roman_numerals.rb
13
+
14
+ # Contains methods to convert integers to Roman numeral strings, and vice versa.
15
+ module RomanNumerals
16
+
17
+ # Maps Roman numeral digits to their integer values
18
+ DIGITS = {
19
+ 'I' => 1,
20
+ 'V' => 5,
21
+ 'X' => 10,
22
+ 'L' => 50,
23
+ 'C' => 100,
24
+ 'D' => 500,
25
+ 'M' => 1000
26
+ }
27
+
28
+ # The largest integer representable as a Roman numerable by this module
29
+ MAX = 3999
30
+
31
+ # Maps some integers to their Roman numeral values
32
+ @@digits_lookup = DIGITS.inject({
33
+ 4 => 'IV',
34
+ 9 => 'IX',
35
+ 40 => 'XL',
36
+ 90 => 'XC',
37
+ 400 => 'CD',
38
+ 900 => 'CM'}) do |memo, pair|
39
+ memo.update({pair.last => pair.first})
40
+ end
41
+
42
+ # Based on Regular Expression Grabbag in the O'Reilly Perl Cookbook, #6.23
43
+ REGEXP = /^M*(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$/i
44
+
45
+ # Converts +int+ to a Roman numeral
46
+ def self.from_integer(int)
47
+ return nil if int < 0 || int > MAX
48
+ remainder = int
49
+ result = ''
50
+ @@digits_lookup.keys.sort.reverse.each do |digit_value|
51
+ while remainder >= digit_value
52
+ remainder -= digit_value
53
+ result += @@digits_lookup[digit_value]
54
+ end
55
+ break if remainder <= 0
56
+ end
57
+ result
58
+ end
59
+
60
+ # Converts +roman_string+, a Roman numeral, to an integer
61
+ def self.to_integer(roman_string)
62
+ return nil unless roman_string.is_roman_numeral?
63
+ last = nil
64
+ roman_string.to_s.upcase.split(//).reverse.inject(0) do |memo, digit|
65
+ if digit_value = DIGITS[digit]
66
+ if last && last > digit_value
67
+ memo -= digit_value
68
+ else
69
+ memo += digit_value
70
+ end
71
+ last = digit_value
72
+ end
73
+ memo
74
+ end
75
+ end
76
+
77
+ # Returns true if +string+ is a Roman numeral.
78
+ def self.is_roman_numeral?(string)
79
+ REGEXP =~ string
80
+ end
81
+ end
82
+
83
+
84
+
85
+ class String
86
+ # Considers string a Roman numeral,
87
+ # and converts it to the corresponding integer.
88
+ def to_i_roman
89
+ RomanNumerals.to_integer(self)
90
+ end
91
+ # Returns true if the subject is a Roman numeral.
92
+ def is_roman_numeral?
93
+ RomanNumerals.is_roman_numeral?(self)
94
+ end
95
+ end
96
+ class Integer
97
+ # Converts this integer to a Roman numeral.
98
+ def to_s_roman
99
+ RomanNumerals.from_integer(self) || ''
100
+ end
101
+ end
102
+
103
+
104
+
105
+ # Integers that look like Roman numerals
106
+ class RomanNumeral
107
+ attr_reader :to_s, :to_i
108
+
109
+ @@all_roman_numerals = []
110
+
111
+ # May be initialized with either a string or an integer
112
+ def initialize(value)
113
+ case value
114
+ when Integer
115
+ @to_s = value.to_s_roman
116
+ @to_i = value
117
+ else
118
+ @to_s = value.to_s
119
+ @to_i = value.to_s.to_i_roman
120
+ end
121
+ @@all_roman_numerals[to_i] = self
122
+ end
123
+
124
+ # Factory method: returns an equivalent existing object if such exists,
125
+ # or a new one
126
+ def self.get(value)
127
+ if value.is_a?(Integer)
128
+ to_i = value
129
+ else
130
+ to_i = value.to_s.to_i_roman
131
+ end
132
+ @@all_roman_numerals[to_i] || RomanNumeral.new(to_i)
133
+ end
134
+
135
+ def inspect
136
+ to_s
137
+ end
138
+
139
+ # Delegates missing methods to Integer, converting arguments to Integer,
140
+ # and converting results back to RomanNumeral
141
+ def method_missing(sym, *args)
142
+ unless to_i.respond_to?(sym)
143
+ raise NoMethodError.new(
144
+ "undefined method '#{sym}' for #{self}:#{self.class}")
145
+ end
146
+ result = to_i.send(sym,
147
+ *args.map {|arg| arg.is_a?(RomanNumeral) ? arg.to_i : arg })
148
+ case result
149
+ when Integer
150
+ RomanNumeral.get(result)
151
+ when Enumerable
152
+ result.map do |element|
153
+ element.is_a?(Integer) ? RomanNumeral.get(element) : element
154
+ end
155
+ else
156
+ result
157
+ end
158
+ end
159
+ end
160
+
161
+
162
+
163
+ # Enables uppercase Roman numerals to be used interchangeably with integers.
164
+ # They are autovivified RomanNumeral constants
165
+ # Synopsis:
166
+ # 4 + IV #=> VIII
167
+ # VIII + 7 #=> XV
168
+ # III ** III #=> XXVII
169
+ # VIII.divmod(III) #=> [II, II]
170
+ # def Object.const_missing sym
171
+ # unless RomanNumerals::REGEXP === sym.to_s
172
+ # raise NameError.new("uninitialized constant: #{sym}")
173
+ # end
174
+ # const_set(sym, RomanNumeral.get(sym))
175
+ # end
176
+
177
+
178
+ def Object.const_missing sym
179
+ if RomanNumerals::REGEXP === sym.to_s
180
+ const_set(sym, RomanNumeral.get(sym))
181
+ return
182
+ end
183
+ super
184
+ end
@@ -0,0 +1,9 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Roman numerals" do
4
+ it "should add roman numerals correctly" do
5
+ IV = RomanNumeral.get(4)
6
+ res = IV + 5
7
+ res.to_s.should == 'IX'
8
+ end
9
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,6 @@
1
+ require 'rspec'
2
+ require 'rspec/autorun'
3
+ require 'romans'
4
+
5
+ # RSpec.configure do |config|
6
+ # end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: romans
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Kristian Mandrup
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-25 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 2
31
+ - 9
32
+ version: 1.2.9
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: Roman numerals library
36
+ email: kmandrup@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - .document
46
+ - .gitignore
47
+ - LICENSE
48
+ - README.rdoc
49
+ - Rakefile
50
+ - VERSION
51
+ - lib/romans.rb
52
+ - spec/romans_spec.rb
53
+ - spec/spec.opts
54
+ - spec/spec_helper.rb
55
+ has_rdoc: true
56
+ homepage: http://github.com/kristianmandrup/romans
57
+ licenses: []
58
+
59
+ post_install_message:
60
+ rdoc_options:
61
+ - --charset=UTF-8
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.3.7
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Roman numerals
87
+ test_files:
88
+ - spec/romans_spec.rb
89
+ - spec/spec_helper.rb