sorted_array_binary 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/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+ Gemfile.lock
15
+
16
+ # YARD artifacts
17
+ .yardoc
18
+ _yardoc
19
+ doc/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ - "jruby-19mode"
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
6
+ gem 'coveralls', :require => false
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Dmitry Maksyoma
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ sorted_array_binary
2
+ ===================
3
+
4
+ [![Build Status](https://travis-ci.org/ledestin/sorted_array_binary.png)](https://travis-ci.org/ledestin/sorted_array_binary)
5
+ [![Coverage Status] (https://coveralls.io/repos/ledestin/sorted_array_binary/badge.png)] (https://coveralls.io/r/ledestin/sorted_array_binary)
6
+ [![Code Climate](https://codeclimate.com/github/ledestin/sorted_array_binary.png)](https://codeclimate.com/github/ledestin/sorted_array_binary)
7
+
8
+ A sorted array using binary search
9
+
10
+ ## Why
11
+
12
+ 1. Neither of the existing sorted arrays gems use binary search (i.e. slow or
13
+ very slow).
14
+ 2. I don't like their source code, so I decided to roll my own, instead of
15
+ contributing.
16
+
17
+ Existing sorted array gems as of Jan 2014:
18
+ * sorted_array (0.0.5)
19
+ * array-sorted (1.1.2)
20
+
21
+ ## Example
22
+
23
+ ```ruby
24
+ require 'sorted_array_binary'
25
+
26
+ # Use standard sorting via <=>.
27
+ array = SortedArrayBinary.new
28
+ array.push 'b', 'a' #=> ['a', 'b']
29
+
30
+ # Use custom sorting block.
31
+ array = SortedArrayBinary.new { |a, b| b <=> a }
32
+ array.push 'a', 'b' #=> ['b', 'a']
33
+ ```
34
+
35
+ ## Performance
36
+
37
+ When #push'ing 1000 random numbers into an array:
38
+ ```
39
+ sorted_array (0.0.5) 1.179088
40
+ array-sorted (1.1.2) 0.076348
41
+ sorted_array_binary (0.0.1) 0.015969
42
+ ```
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new
6
+ task :default => :spec
7
+
8
+ task :gem do
9
+ system 'gem build *.gemspec'
10
+ end
@@ -0,0 +1,216 @@
1
+ # Copyright (C) 2014 by Dmitry Maksyoma <ledestin@gmail.com>
2
+
3
+ # Automatically sorted array (by using binary search). Nils aren't allowed.
4
+ # Methods that reorder elements are not implemented, as well as #[]= and #fill.
5
+ #
6
+ # = Example
7
+ # require 'sorted_array_binary'
8
+ #
9
+ # # Use standard sorting via <=>.
10
+ # array = SortedArrayBinary.new
11
+ # array.push 'b', 'a' #=> ['a', 'b']
12
+ #
13
+ # # Use custom sorting block.
14
+ # array = SortedArrayBinary.new { |a, b| b <=> a }
15
+ # array.push 'a', 'b' #=> ['b', 'a']
16
+ class SortedArrayBinary < Array
17
+ # {{{2 ComparisonState
18
+ class ComparisonState #:nodoc:
19
+ def initialize state
20
+ raise ArgumentError, "invalid state: #{state.inspect}" \
21
+ unless state && state >= -1 && state <= 1
22
+
23
+ @state = state
24
+ end
25
+
26
+ def equal?
27
+ @state == 0
28
+ end
29
+
30
+ def greater?
31
+ @state == 1
32
+ end
33
+
34
+ def less?
35
+ @state == -1
36
+ end
37
+ end
38
+ # }}}2
39
+
40
+ class InvalidSortBlock < RuntimeError #:nodoc:
41
+ end
42
+
43
+ def self._check_for_nil *objs #:nodoc:
44
+ raise ArgumentError, "nils aren't allowed into sorted array" \
45
+ if objs.include?(nil)
46
+ end
47
+
48
+ alias :old_insert :insert
49
+ private :old_insert
50
+ alias :old_sort! :sort!
51
+ private :old_sort!
52
+
53
+ def initialize *args, &b
54
+ @sort_block = proc { |a, b| a <=> b }
55
+
56
+ # Passed sort block.
57
+ if args.size == 0 && block_given?
58
+ @sort_block = b
59
+ super()
60
+ return
61
+ end
62
+
63
+ if args.size == 1
64
+ # Passed initial array.
65
+ if args.first.respond_to? :each
66
+ self.class._check_for_nil *args.first
67
+ super *args
68
+ old_sort!
69
+ return
70
+ end
71
+
72
+ # Passed size and block.
73
+ if block_given?
74
+ super *args, &b
75
+ self.class._check_for_nil *self
76
+ old_sort!
77
+ return
78
+ end
79
+
80
+ # Passed size, but not obj, which means fill with nils.
81
+ raise ArgumentError, "can't fill array with nils" \
82
+ if args.first.is_a? Numeric
83
+ end
84
+
85
+ super
86
+ end
87
+
88
+ # Not implemented methods.
89
+ #
90
+ # The following methods are not implemented mostly because they change order
91
+ # of elements. The rest ([]= and fill) arguably aren't useful on a sorted
92
+ # array.
93
+ def _not_implemented *args #:nodoc:
94
+ raise NotImplementedError
95
+ end
96
+
97
+ [:[]=, :fill, :insert, :reverse!, :rotate!, :shuffle!, :sort!, :unshift].
98
+ each { |m|
99
+ alias_method m, :_not_implemented
100
+ }
101
+
102
+ # Same as Array#collect!, but:
103
+ # * Disallow nils in the resulting array.
104
+ # * The resulting array is sorted.
105
+ def collect! &b
106
+ replace(collect &b)
107
+ end
108
+ alias :map! :collect!
109
+
110
+ # Same as Array#concat, but:
111
+ # * Disallow nils in the passed array.
112
+ # * The resulting array is sorted.
113
+ def concat other_ary
114
+ _add *other_ary
115
+ end
116
+
117
+ # Same as Array#flatten!, but:
118
+ # * Disallow nils in the resulting array.
119
+ # * The resulting array is sorted.
120
+ def flatten! *args
121
+ replace(flatten *args)
122
+ end
123
+
124
+ # Add objects to array, automatically placing them according to sort order.
125
+ # Disallow nils.
126
+ def push *objs
127
+ _add *objs
128
+ end
129
+ alias :<< :push
130
+
131
+ # Same as Array#replace, but:
132
+ # * Disallow nils in @other_ary.
133
+ # * The resulting array is sorted.
134
+ def replace other_ary
135
+ self.class._check_for_nil *other_ary
136
+ super
137
+ old_sort!
138
+ self
139
+ end
140
+
141
+ #private
142
+ # Name the following methods starting with underscore so as not to pollute
143
+ # Array namespace. They are considered private, but for testing purposes are
144
+ # left public.
145
+
146
+ def _add *objs #:nodoc:
147
+ self.class._check_for_nil *objs
148
+ objs.each { |obj|
149
+ old_insert _find_insert_position(obj), obj
150
+ }
151
+ self
152
+ end
153
+
154
+ def _check_can_calc_boundary? #:nodoc:
155
+ raise "can't calc boundary on empty array" if empty?
156
+ end
157
+
158
+ def _compare a, b #:nodoc:
159
+ ComparisonState.new(ret = @sort_block.call(a, b))
160
+ rescue ArgumentError
161
+ raise InvalidSortBlock,
162
+ "sort block returned invalid value: #{ret.inspect}"
163
+ end
164
+
165
+ def _find_insert_position element_to_place #:nodoc:
166
+ return 0 if empty?
167
+
168
+ start_idx, end_idx = 0, size - 1
169
+ loop {
170
+ middle_idx = _middle_element_index(start_idx, end_idx)
171
+ middle_el = self[middle_idx]
172
+ after_middle_idx = middle_idx + 1
173
+
174
+ comparison_state = _compare(element_to_place, middle_el)
175
+
176
+ # 1. Equals to the middle element. Insert after el.
177
+ return after_middle_idx if comparison_state.equal?
178
+
179
+ # 2. Less than the middle element.
180
+ if comparison_state.less?
181
+ # There's nothing to the left. So insert it as the first element.
182
+ return 0 if _left_boundary? middle_idx
183
+
184
+ end_idx = middle_idx - 1
185
+ next
186
+ end
187
+
188
+ # 3. Greater than the middle element.
189
+ #
190
+ # Right boundary? Put element_to_place after the last (middle) element.
191
+ return after_middle_idx if _right_boundary? middle_idx
192
+
193
+ # Less than after middle element? Put it right before it!
194
+ after_middle_el = self[after_middle_idx]
195
+ ret = _compare(element_to_place, after_middle_el)
196
+ return after_middle_idx if ret.equal? || ret.less?
197
+
198
+ # Proceeed to divide the right part.
199
+ start_idx = after_middle_idx
200
+ }
201
+ end
202
+
203
+ def _left_boundary? idx #:nodoc:
204
+ _check_can_calc_boundary?
205
+ idx == 0
206
+ end
207
+
208
+ def _middle_element_index start, ending #:nodoc:
209
+ start + (ending - start)/2
210
+ end
211
+
212
+ def _right_boundary? idx #:nodoc:
213
+ _check_can_calc_boundary?
214
+ idx == size - 1
215
+ end
216
+ end
@@ -0,0 +1,13 @@
1
+ require 'frugal_timeout'
2
+
3
+ MonotonicTime = FrugalTimeout::MonotonicTime
4
+
5
+ def say msg, sec
6
+ printf "%-24s %f\n", msg, sec
7
+ end
8
+
9
+ @ar = []
10
+ COUNT = 1000
11
+ COUNT.times {
12
+ @ar << rand(COUNT)
13
+ }
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require './common'
4
+ require '../lib/sorted_array_binary'
5
+
6
+ sec = MonotonicTime.measure { @ar.sort }
7
+ say 'sorting', sec
8
+
9
+ sec = MonotonicTime.measure {
10
+ sa = SortedArrayBinary.new
11
+ sa.push *@ar
12
+ }
13
+ say 'pushing into SortedArray', sec
14
+
15
+ sec = MonotonicTime.measure {
16
+ SortedArrayBinary.new @ar
17
+ }
18
+ say 'SortedArray.new', sec
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'frugal_timeout'
4
+ require 'sorted_array'
5
+ require 'array-sorted'
6
+ require './common'
7
+ require '../lib/sorted_array_binary'
8
+
9
+ def measure sorted_array_name, sorted_array_instance
10
+ sec = MonotonicTime.measure {
11
+ @ar.each { |el|
12
+ sorted_array_instance.push el
13
+ }
14
+ }
15
+ say sorted_array_name, sec
16
+ end
17
+
18
+ measure 'sorted_array',
19
+ SortedArray::SortedArray.new(SortedArray::DefaultSorter.new(:to_i))
20
+ measure 'array-sorted', Array::Sorted.new
21
+ measure 'sorted_array_binary', SortedArrayBinary.new
@@ -0,0 +1,16 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'sorted_array_binary'
3
+ s.version = '0.0.1'
4
+ s.date = '2014-01-29'
5
+ s.summary = 'Sorted array'
6
+ s.description = 'Sorted array using binary search'
7
+ s.authors = ['Dmitry Maksyoma']
8
+ s.email = 'ledestin@gmail.com'
9
+ s.files = `git ls-files`.split($\)
10
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
11
+ s.require_paths = ['lib']
12
+ s.homepage = 'https://github.com/ledestin/sorted_array_binary'
13
+
14
+ s.add_development_dependency 'rspec', '>= 2.13'
15
+ s.add_development_dependency 'hitimes', '~> 1.2'
16
+ end
@@ -0,0 +1,352 @@
1
+ require 'rspec'
2
+ require 'spec_helper'
3
+ require 'sorted_array_binary'
4
+
5
+ describe SortedArrayBinary do
6
+ before :each do
7
+ @ar = SortedArrayBinary.new
8
+ end
9
+
10
+ # {{{2 self._check_for_nil
11
+ context 'self._check_for_nil' do
12
+ it "raises exception if there's nil in passed objs" do
13
+ expect {
14
+ SortedArrayBinary._check_for_nil 'a', nil
15
+ }.to raise_error ArgumentError
16
+ end
17
+
18
+ it "doesn't raise exception if there's no nil in passed objs" do
19
+ expect {
20
+ SortedArrayBinary._check_for_nil 'a', 'b'
21
+ }.not_to raise_error
22
+ end
23
+ end
24
+
25
+ # {{{2 self.new
26
+ context 'self.new' do
27
+ it 'if passed size and obj, fills it' do
28
+ @ar = SortedArrayBinary.new 5, 'a'
29
+ @ar.should == ['a']*5
30
+ end
31
+
32
+ it 'if passed just size, raises exception' do
33
+ expect { SortedArrayBinary.new 5 }.to raise_error ArgumentError
34
+ end
35
+
36
+ it 'if passed single non-numeric argument, calls Array#new' do
37
+ expect { SortedArrayBinary.new 'a' }.to raise_error TypeError
38
+ end
39
+
40
+ context 'if passed array,' do
41
+ it 'sorts it' do
42
+ @ar = SortedArrayBinary.new ['b', 'a']
43
+ @ar.should == ['a', 'b']
44
+ end
45
+
46
+ it 'raises exception if nil found in passed array' do
47
+ expect { SortedArrayBinary.new [nil] }.to raise_error ArgumentError
48
+ end
49
+ end
50
+
51
+ it 'if passed size and block, fills it and sorts it' do
52
+ @ar = SortedArrayBinary.new(5) { |i| i == 0 ? 10 : i }
53
+ @ar.should == [1, 2, 3, 4, 10]
54
+ end
55
+
56
+ it 'if passed sorting block, resulting array is sorted using it' do
57
+ @ar = SortedArrayBinary.new { |a, b| b <=> a }
58
+ @ar.push 'a', 'b'
59
+ @ar.should == ['b', 'a']
60
+ end
61
+ end
62
+
63
+ # {{{2 Not implemented
64
+ context 'raises NotImplementedError exception when called' do
65
+ it '#[]=' do
66
+ expect { @ar[0] = 'a' }.to raise_error NotImplementedError
67
+ end
68
+
69
+ it '#fill' do
70
+ expect { @ar.fill nil }.to raise_error NotImplementedError
71
+ end
72
+
73
+ [:insert, :reverse!, :rotate!, :shuffle!, :sort!, :unshift].
74
+ each { |m|
75
+ it "##{m}" do
76
+ expect { @ar.send m }.to raise_error NotImplementedError
77
+ end
78
+ }
79
+ end
80
+
81
+ # {{{2 #collect!
82
+ [:collect!, :map!].each { |method|
83
+ context "##{method}" do
84
+ it 'after it, array is sorted' do
85
+ @ar.push 'a', 'b', 'c'
86
+ @ar.send(method) { |el|
87
+ case el
88
+ when 'a' then 9
89
+ when 'b' then 3
90
+ when 'c' then 1
91
+ end
92
+ }
93
+ @ar.should == [1, 3, 9]
94
+ end
95
+
96
+ it 'raises exception if one of resulting elements is nil' do
97
+ @ar.push 'a'
98
+ expect { @ar.send(method) { nil } }.to raise_error ArgumentError
99
+ @ar.should == ['a']
100
+ end
101
+ end
102
+ }
103
+
104
+ # {{{2 #concat
105
+ it '#concat adds another array and everything is sorted' do
106
+ @ar.push 'c'
107
+ @ar.concat ['a', 'b']
108
+ @ar.should == ['a', 'b', 'c']
109
+ end
110
+
111
+ # {{{2 #flatten!
112
+ context '#flatten!' do
113
+ it 'flattens array' do
114
+ @ar.push [1, 2], [4, 3]
115
+ @ar.flatten!
116
+ @ar.should == [1, 2, 3, 4]
117
+ end
118
+
119
+ it 'raises exception if resulting array contains nil' do
120
+ @ar.push [nil, 1]
121
+ expect { @ar.flatten! }.to raise_error ArgumentError
122
+ @ar.should == [[nil, 1]]
123
+ end
124
+ end
125
+
126
+ # {{{2 #push
127
+ [:<<, :push].each { |method|
128
+ context "##{method}" do
129
+ it 'adds an element to array' do
130
+ @ar.send method, 'a'
131
+ @ar.should == ['a']
132
+ end
133
+
134
+ it 'adds 2 elements to array' do
135
+ @ar.send method, 'a', 'b'
136
+ @ar.should == ['a', 'b']
137
+ end
138
+
139
+ it 'adds elements in random order, but the result is sorted' do
140
+ @ar.send method, 'b', 'a', 'd', 'c'
141
+ @ar.should == ['a', 'b', 'c', 'd']
142
+ @ar.send method, 'e'
143
+ @ar.should == ['a', 'b', 'c', 'd', 'e']
144
+ end
145
+
146
+ it 'adds element in random order, but sorting is done via sort block' do
147
+ @ar = SortedArrayBinary.new { |a, b| b <=> a }
148
+ @ar.push 'c', 'd'
149
+ @ar.push 'a', 'b'
150
+ @ar.should == ['d', 'c', 'b', 'a']
151
+ end
152
+
153
+ it 'raises exception if nil is passed' do
154
+ expect { @ar.send method, nil }.to raise_error ArgumentError
155
+ end
156
+ end
157
+ }
158
+
159
+ # {{{2 #replace
160
+ context '#replace' do
161
+ it '#replace replaces array, the resulting array is sorted' do
162
+ @ar.push 'a'
163
+ @ar.replace ['c', 'b']
164
+ @ar.should == ['b', 'c']
165
+ end
166
+
167
+ it "doesn't allow nils" do
168
+ expect { @ar.replace [nil] }.to raise_error ArgumentError
169
+ end
170
+ end
171
+
172
+ # {{{2 #_compare
173
+ context '#_compare' do
174
+ context 'sort block not given' do
175
+ it 'returns :equal if arguments are equal' do
176
+ @ar._compare(1, 1).equal?.should be_true
177
+ end
178
+
179
+ it 'returns :less if arg1 < arg2' do
180
+ @ar._compare(1, 2).less?.should be_true
181
+ end
182
+
183
+ it 'returns :greater if arg1 > arg2' do
184
+ @ar._compare(2, 1).greater?.should be_true
185
+ end
186
+ end
187
+
188
+ context 'sort block given' do
189
+ before :each do
190
+ @ar = SortedArrayBinary.new { |a, b| b <=> a }
191
+ end
192
+
193
+ it 'returns :equal if arguments are equal' do
194
+ @ar._compare(1, 1).equal?.should be_true
195
+ end
196
+
197
+ it 'returns :less if arg1 < arg2' do
198
+ @ar._compare(2, 1).less?.should be_true
199
+ end
200
+
201
+ it 'returns :greater if arg1 > arg2' do
202
+ @ar._compare(1, 2).greater?.should be_true
203
+ end
204
+
205
+ it 'raises exception if block returns value outside of -1, 0, 1' do
206
+ @ar = SortedArrayBinary.new { 'a' }
207
+ expect {
208
+ @ar.push 1, 2
209
+ }.to raise_error SortedArrayBinary::InvalidSortBlock
210
+ end
211
+ end
212
+ end
213
+
214
+ # {{{2 #_find_insert_position
215
+ context '#_find_insert_position' do
216
+ it 'returns 0 if array is empty' do
217
+ @ar._find_insert_position('a').should == 0
218
+ end
219
+
220
+ context 'and array contains single element,' do
221
+ it 'returns 1 if the first element is less than the passed elementt' do
222
+ @ar.push 'a'
223
+ @ar._find_insert_position('b').should == 1
224
+ end
225
+
226
+ it 'returns 0 if the first element is greater than the passed elementt' do
227
+ @ar.push 'b'
228
+ @ar._find_insert_position('a').should == 0
229
+ end
230
+
231
+ it 'returns 1 if the first element is equal to the passed elementt' do
232
+ @ar.push 'a'
233
+ @ar._find_insert_position('a').should == 1
234
+ end
235
+ end
236
+
237
+ context 'and array contains 2 elements,' do
238
+ it 'returns 2 if passed element is greater than 2nd element' do
239
+ @ar.push 'a', 'b'
240
+ @ar._find_insert_position('c').should == 2
241
+ end
242
+
243
+ it 'returns 1 if passed element is less than 2nd element' do
244
+ @ar.push 'a', 'c'
245
+ @ar._find_insert_position('b').should == 1
246
+ end
247
+
248
+ it 'returns 0 if passed element is less than 1st element' do
249
+ @ar.push 'b', 'c'
250
+ @ar._find_insert_position('a').should == 0
251
+ end
252
+ end
253
+
254
+ context 'and array context 4 elements,' do
255
+ it 'returns 1 if passed element is greater than 1st element' do
256
+ @ar.push 'a', 'c', 'd'
257
+ @ar._find_insert_position('b').should == 1
258
+ end
259
+ end
260
+ end
261
+
262
+ # {{{2 #_middle_element_index
263
+ context '_middle_element_index' do
264
+ it "returns first element index if there's one element" do
265
+ @ar._middle_element_index(0, 0).should == 0
266
+ @ar._middle_element_index(1, 1).should == 1
267
+ end
268
+
269
+ it 'returns 0 if there are 2 elements in the array' do
270
+ @ar._middle_element_index(0, 1).should == 0
271
+ end
272
+
273
+ it 'returns 1 if there are 3 elements in the array' do
274
+ @ar._middle_element_index(0, 2).should == 1
275
+ end
276
+
277
+ it 'returns 1 if there are 4 elements in the array' do
278
+ @ar._middle_element_index(0, 3).should == 1
279
+ end
280
+ end
281
+
282
+ # {{{2 #_left_boundary, #_right_boundary
283
+ context '#_left_boundary, #_right_boundary' do
284
+ context 'left' do
285
+ it "returns true if it's left boundary?" do
286
+ @ar.push 'a'
287
+ @ar._left_boundary?(0).should == true
288
+ end
289
+
290
+ it "returns false if it's not left boundary?" do
291
+ @ar.push 'a'
292
+ @ar._left_boundary?(1).should == false
293
+ end
294
+
295
+ it 'raises exception if array is empty' do
296
+ expect {
297
+ @ar._left_boundary?(0)
298
+ }.to raise_error
299
+ end
300
+ end
301
+
302
+ context 'right' do
303
+ it "returns true if it's right boundary?" do
304
+ @ar.push 'a', 'b'
305
+ @ar._right_boundary?(1).should == true
306
+ end
307
+
308
+ it "returns false if it's not right boundary?" do
309
+ @ar.push 'a', 'b'
310
+ @ar._right_boundary?(0).should == false
311
+ end
312
+
313
+ it 'raises exception if array is empty' do
314
+ expect {
315
+ @ar._right_boundary?(0)
316
+ }.to raise_error
317
+ end
318
+ end
319
+ end
320
+ # }}}2
321
+ end
322
+
323
+ describe SortedArrayBinary::ComparisonState do
324
+ [nil, -2, 2].each { |state|
325
+ it "allows only valid state in" do
326
+ expect {
327
+ SortedArrayBinary::ComparisonState.new state
328
+ }.to raise_error ArgumentError
329
+ end
330
+ }
331
+
332
+ it 'is equal? if state is 0' do
333
+ state = SortedArrayBinary::ComparisonState.new 0
334
+ state.equal?.should be_true
335
+ state.less?.should be_false
336
+ state.greater?.should be_false
337
+ end
338
+
339
+ it 'is greater? if state is 1' do
340
+ state = SortedArrayBinary::ComparisonState.new 1
341
+ state.greater?.should be_true
342
+ state.equal?.should be_false
343
+ state.less?.should be_false
344
+ end
345
+
346
+ it 'is less? if state is -1' do
347
+ state = SortedArrayBinary::ComparisonState.new -1
348
+ state.less?.should be_true
349
+ state.equal?.should be_false
350
+ state.greater?.should be_false
351
+ end
352
+ end
@@ -0,0 +1,2 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sorted_array_binary
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Dmitry Maksyoma
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-01-29 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: '2.13'
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: '2.13'
30
+ - !ruby/object:Gem::Dependency
31
+ name: hitimes
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.2'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.2'
46
+ description: Sorted array using binary search
47
+ email: ledestin@gmail.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - .coveralls.yml
53
+ - .gitignore
54
+ - .rspec
55
+ - .travis.yml
56
+ - Gemfile
57
+ - LICENSE
58
+ - README.md
59
+ - Rakefile
60
+ - lib/sorted_array_binary.rb
61
+ - perf-tests/common.rb
62
+ - perf-tests/perf-vs-sort
63
+ - perf-tests/perf-vs-sorted_array
64
+ - sorted_array_binary.gemspec
65
+ - spec/sorted_array_binary_spec.rb
66
+ - spec/spec_helper.rb
67
+ homepage: https://github.com/ledestin/sorted_array_binary
68
+ licenses: []
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 1.8.23
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: Sorted array
91
+ test_files:
92
+ - spec/sorted_array_binary_spec.rb
93
+ - spec/spec_helper.rb
94
+ has_rdoc: