algorithmable 0.9.0 → 0.10.0
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 +4 -4
- data/README.md +1 -1
- data/lib/algorithmable/data_structs/bag.rb +1 -0
- data/lib/algorithmable/data_structs/deque.rb +29 -14
- data/lib/algorithmable/data_structs/linked_list.rb +1 -0
- data/lib/algorithmable/data_structs/ordered_symbol_table.rb +5 -231
- data/lib/algorithmable/data_structs/queue.rb +1 -2
- data/lib/algorithmable/data_structs/stack.rb +1 -2
- data/lib/algorithmable/search/{binary.rb → binary_search.rb} +2 -2
- data/lib/algorithmable/search/binary_search_tree.rb +291 -0
- data/lib/algorithmable/searches.rb +14 -0
- data/lib/algorithmable/version.rb +1 -1
- data/lib/algorithmable.rb +1 -1
- metadata +5 -4
- data/lib/algorithmable/search.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0f425945316b488e5f78067168f54dd56415392
|
4
|
+
data.tar.gz: c9dd9353cf0883de156a9860472d18233c227ea2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fd0bb3ef1d1f3fe956aaa0fce478fcd1dc474d54b02ea86619802873ab620d181f3e49c7fefaf86c805fdd917f69e00d5a2e6f50f5971d97afb2462a91d62af
|
7
|
+
data.tar.gz: 5bdbf61cfb48f980c4d3d3721b7fc48a3f2c6aa26a249753b27bae965e83b41886855cbdae5e5b5904cbc621a3ee03456b826ee0e9345c1b59e338340dee923e
|
data/README.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module Algorithmable
|
2
2
|
module DataStructs
|
3
3
|
class Deque
|
4
|
-
include Enumerable
|
5
4
|
include Algorithmable::Errors
|
6
5
|
|
7
6
|
Node = Struct.new(:prev, :next, :item)
|
7
|
+
private_constant :Node
|
8
|
+
|
8
9
|
attr_reader :size
|
9
10
|
|
10
11
|
def initialize(collection = [])
|
@@ -89,23 +90,37 @@ module Algorithmable
|
|
89
90
|
end
|
90
91
|
|
91
92
|
# represent fifo iterator
|
92
|
-
def each
|
93
|
-
|
94
|
-
node = @front
|
95
|
-
while node
|
96
|
-
yield node.item
|
97
|
-
node = node.next
|
98
|
-
end
|
93
|
+
def each(&block)
|
94
|
+
collect_items(:forward).each(&block)
|
99
95
|
end
|
100
96
|
|
101
97
|
# represent lifo iterator
|
102
|
-
def reverse_each
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
98
|
+
def reverse_each(&block)
|
99
|
+
collect_items(:backward).each(&block)
|
100
|
+
end
|
101
|
+
|
102
|
+
def to_a
|
103
|
+
each.to_a
|
104
|
+
end
|
105
|
+
|
106
|
+
def map(&block)
|
107
|
+
each.map(&block)
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def collect_items(order)
|
113
|
+
variable = order == :backward ? @back : @front
|
114
|
+
action = order == :backward ? :prev : :next
|
115
|
+
items = []
|
116
|
+
if variable
|
117
|
+
node = variable
|
118
|
+
while node
|
119
|
+
items << node.item
|
120
|
+
node = node.public_send action
|
121
|
+
end
|
108
122
|
end
|
123
|
+
items
|
109
124
|
end
|
110
125
|
end
|
111
126
|
end
|
@@ -1,239 +1,13 @@
|
|
1
1
|
module Algorithmable
|
2
2
|
module DataStructs
|
3
|
-
#
|
4
|
-
# Ordered Symbol Table. Implementation using Unbalanced Binary Tree.
|
5
|
-
#
|
6
3
|
class OrderedSymbolTable
|
7
|
-
|
8
|
-
@key_type = key_type
|
9
|
-
@value_type = value_type
|
10
|
-
@root = nil
|
11
|
-
end
|
12
|
-
|
13
|
-
def empty?
|
14
|
-
!size.nonzero?
|
15
|
-
end
|
16
|
-
|
17
|
-
def size
|
18
|
-
node_size(@root)
|
19
|
-
end
|
20
|
-
|
21
|
-
def key?(key)
|
22
|
-
assert_key_type(key)
|
23
|
-
!self[key].nil?
|
24
|
-
end
|
25
|
-
|
26
|
-
def [](key)
|
27
|
-
assert_key_type(key)
|
28
|
-
impl_get(@root, key)
|
29
|
-
end
|
30
|
-
|
31
|
-
def []=(key, value)
|
32
|
-
assert_value_type(value)
|
33
|
-
assert_key_type(key)
|
34
|
-
delete key
|
35
|
-
@root = impl_put(@root, key, value)
|
36
|
-
check_tree
|
37
|
-
end
|
38
|
-
|
39
|
-
def delete_min
|
40
|
-
@root = impl_delete_min @root
|
41
|
-
check_tree
|
42
|
-
end
|
43
|
-
|
44
|
-
def delete_max
|
45
|
-
@root = impl_delete_max @root
|
46
|
-
check_tree
|
47
|
-
end
|
48
|
-
|
49
|
-
def delete(key)
|
50
|
-
assert_key_type(key)
|
51
|
-
@root = impl_delete(@root, key)
|
52
|
-
check_tree
|
53
|
-
end
|
54
|
-
|
55
|
-
def min
|
56
|
-
impl_min(@root).key
|
57
|
-
end
|
58
|
-
|
59
|
-
def max
|
60
|
-
impl_max(@root).key
|
61
|
-
end
|
62
|
-
|
63
|
-
def floor(key)
|
64
|
-
assert_key_type(key)
|
65
|
-
return unless key || empty?
|
66
|
-
found = impl_floor(@root, key)
|
67
|
-
return unless found
|
68
|
-
found.key
|
69
|
-
end
|
70
|
-
|
71
|
-
def ceiling(key)
|
72
|
-
assert_key_type(key)
|
73
|
-
return unless key || empty?
|
74
|
-
found = impl_ceiling(@root, key)
|
75
|
-
return unless found
|
76
|
-
found.key
|
77
|
-
end
|
78
|
-
|
79
|
-
def select(integer)
|
80
|
-
return if integer < 0 || integer >= size
|
81
|
-
found = impl_select(@root, integer)
|
82
|
-
found.key
|
83
|
-
end
|
84
|
-
|
85
|
-
def rank(key)
|
86
|
-
assert_key_type(key)
|
87
|
-
return unless key
|
88
|
-
impl_rank @root, key
|
89
|
-
end
|
90
|
-
|
91
|
-
private
|
92
|
-
|
93
|
-
def check_tree
|
94
|
-
true
|
95
|
-
end
|
96
|
-
|
97
|
-
def assert_value_type(value)
|
98
|
-
fail "Type expectation not met. Use value type `#{@value_type}` instead." unless value.is_a? @value_type
|
99
|
-
end
|
100
|
-
|
101
|
-
def assert_key_type(key)
|
102
|
-
fail "Type expectation not met. Use key type `#{@key_type}` instead." unless key.is_a? @key_type
|
103
|
-
end
|
104
|
-
|
105
|
-
def impl_rank(node, key)
|
106
|
-
return 0 unless node
|
107
|
-
comparison = key <=> node.key
|
108
|
-
if comparison < 0
|
109
|
-
impl_rank(node.left, key)
|
110
|
-
elsif comparison > 0
|
111
|
-
1 + node_size(node.left) + impl_rank(node.right, key)
|
112
|
-
else
|
113
|
-
node_size node.left
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def impl_select(node, index)
|
118
|
-
return unless node
|
119
|
-
left_size = node_size(node.left)
|
120
|
-
if left_size > index
|
121
|
-
impl_select(node.left, index)
|
122
|
-
elsif left_size < index
|
123
|
-
impl_select node.right, (index - left_size - 1)
|
124
|
-
else
|
125
|
-
node
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def impl_ceiling(node, key)
|
130
|
-
return unless node
|
131
|
-
comparison = key <=> node.key
|
132
|
-
return node if 0 == comparison
|
133
|
-
if comparison < 0
|
134
|
-
found = impl_ceiling(node.left, key)
|
135
|
-
return found if found
|
136
|
-
return node
|
137
|
-
end
|
138
|
-
impl_ceiling node.right, key
|
139
|
-
end
|
140
|
-
|
141
|
-
def impl_floor(node, key)
|
142
|
-
return unless node
|
143
|
-
comparison = key <=> node.key
|
144
|
-
return node if 0 == comparison
|
145
|
-
return impl_floor(node.left, key) if comparison < 0
|
146
|
-
found = impl_floor(node.right, key)
|
147
|
-
return found if found
|
148
|
-
node
|
149
|
-
end
|
150
|
-
|
151
|
-
def impl_delete(node, key)
|
152
|
-
return unless node
|
153
|
-
comparison = key <=> node.key
|
154
|
-
if comparison < 0
|
155
|
-
node.left = impl_delete(node.left, key)
|
156
|
-
elsif comparison > 0
|
157
|
-
node.right = impl_delete(node.right, key)
|
158
|
-
else
|
159
|
-
return unless node.left || node.right
|
160
|
-
temp = node
|
161
|
-
node = impl_min(temp.right)
|
162
|
-
node.right = impl_delete_min(temp.right)
|
163
|
-
node.left = temp.left
|
164
|
-
end
|
165
|
-
node.size = computed_node_size(node)
|
166
|
-
node
|
167
|
-
end
|
168
|
-
|
169
|
-
def impl_max(node)
|
170
|
-
return node unless node.right
|
171
|
-
impl_max node.right
|
172
|
-
end
|
173
|
-
|
174
|
-
def impl_min(node)
|
175
|
-
return node unless node.left
|
176
|
-
impl_min node.left
|
177
|
-
end
|
178
|
-
|
179
|
-
def impl_delete_max(node)
|
180
|
-
return node.left unless node.right
|
181
|
-
node.right = impl_delete_max(node.right)
|
182
|
-
node.size = computed_node_size(node)
|
183
|
-
node
|
184
|
-
end
|
185
|
-
|
186
|
-
def impl_delete_min(node)
|
187
|
-
return node.right unless node.left
|
188
|
-
node.left = impl_delete_min(node.left)
|
189
|
-
node.size = computed_node_size(node)
|
190
|
-
node
|
191
|
-
end
|
192
|
-
|
193
|
-
def impl_put(node, key, value)
|
194
|
-
return Node.new(key, value, 1) unless node
|
195
|
-
comparison = key <=> node.key
|
196
|
-
if comparison < 0
|
197
|
-
node.left = impl_put(node.left, key, value)
|
198
|
-
elsif comparison > 0
|
199
|
-
node.right = impl_put(node.right, key, value)
|
200
|
-
else
|
201
|
-
node.value = value
|
202
|
-
end
|
203
|
-
node.size = computed_node_size(node)
|
204
|
-
node
|
205
|
-
end
|
206
|
-
|
207
|
-
def impl_get(node, key)
|
208
|
-
return unless node
|
209
|
-
comparison = key <=> node.key
|
210
|
-
if comparison < 0
|
211
|
-
impl_get(node.left, key)
|
212
|
-
elsif comparison > 0
|
213
|
-
impl_get(node.right, key)
|
214
|
-
else
|
215
|
-
node.value
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
def node_size(node)
|
220
|
-
node.nil? ? 0 : node.size
|
221
|
-
end
|
222
|
-
|
223
|
-
def computed_node_size(node)
|
224
|
-
1 + node_size(node.left) + node_size(node.right)
|
225
|
-
end
|
4
|
+
extend Forwardable
|
226
5
|
|
227
|
-
|
228
|
-
attr_accessor :key, :value, :left, :right, :size
|
6
|
+
def_delegators :@imp, :[]=, :[], :key?, :empty?, :size, :keys, :max, :min, :floor, :ceiling, :rank, :delete
|
229
7
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
@left = nil
|
234
|
-
@right = nil
|
235
|
-
@size = size
|
236
|
-
end
|
8
|
+
def initialize(key_type, value_type)
|
9
|
+
search_strategy_factory = Object.new.extend Algorithmable::Searches
|
10
|
+
@imp = search_strategy_factory.new_binary_search_tree(key_type, value_type)
|
237
11
|
end
|
238
12
|
end
|
239
13
|
end
|
@@ -2,10 +2,9 @@ module Algorithmable
|
|
2
2
|
module DataStructs
|
3
3
|
class Queue
|
4
4
|
include Algorithmable::Errors
|
5
|
-
include Enumerable
|
6
5
|
extend Forwardable
|
7
6
|
|
8
|
-
def_delegators :@imp, :empty?, :size, :each
|
7
|
+
def_delegators :@imp, :empty?, :size, :each, :map, :to_a
|
9
8
|
|
10
9
|
def initialize(collection = [])
|
11
10
|
@imp = Deque.new collection
|
@@ -2,10 +2,9 @@ module Algorithmable
|
|
2
2
|
module DataStructs
|
3
3
|
class Stack
|
4
4
|
include Algorithmable::Errors
|
5
|
-
include Enumerable
|
6
5
|
extend Forwardable
|
7
6
|
|
8
|
-
def_delegators :@imp, :empty?, :size, :each
|
7
|
+
def_delegators :@imp, :empty?, :size, :each, :map, :to_a
|
9
8
|
|
10
9
|
def initialize(collection = [])
|
11
10
|
@imp = Deque.new
|
@@ -0,0 +1,291 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Searches
|
3
|
+
class BinarySearchTree
|
4
|
+
def initialize(key_type, value_type)
|
5
|
+
@key_type = key_type
|
6
|
+
@value_type = value_type
|
7
|
+
@root = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def empty?
|
11
|
+
!size.nonzero?
|
12
|
+
end
|
13
|
+
|
14
|
+
def size
|
15
|
+
node_size(@root)
|
16
|
+
end
|
17
|
+
|
18
|
+
def key?(key)
|
19
|
+
assert_key_type(key)
|
20
|
+
!self[key].nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
def [](key)
|
24
|
+
assert_key_type(key)
|
25
|
+
impl_get(@root, key)
|
26
|
+
end
|
27
|
+
|
28
|
+
def []=(key, value)
|
29
|
+
assert_value_type(value)
|
30
|
+
assert_key_type(key)
|
31
|
+
delete key
|
32
|
+
@root = impl_put(@root, key, value)
|
33
|
+
check_tree_consistency
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete_min
|
37
|
+
@root = impl_delete_min @root
|
38
|
+
check_tree_consistency
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete_max
|
42
|
+
@root = impl_delete_max @root
|
43
|
+
check_tree_consistency
|
44
|
+
end
|
45
|
+
|
46
|
+
def delete(key)
|
47
|
+
assert_key_type(key)
|
48
|
+
@root = impl_delete(@root, key)
|
49
|
+
check_tree_consistency
|
50
|
+
end
|
51
|
+
|
52
|
+
def min
|
53
|
+
return if empty?
|
54
|
+
impl_min(@root).key
|
55
|
+
end
|
56
|
+
|
57
|
+
def max
|
58
|
+
return if empty?
|
59
|
+
impl_max(@root).key
|
60
|
+
end
|
61
|
+
|
62
|
+
def floor(key)
|
63
|
+
assert_key_type(key)
|
64
|
+
return unless key || empty?
|
65
|
+
found = impl_floor(@root, key)
|
66
|
+
return unless found
|
67
|
+
found.key
|
68
|
+
end
|
69
|
+
|
70
|
+
def ceiling(key)
|
71
|
+
assert_key_type(key)
|
72
|
+
return unless key || empty?
|
73
|
+
found = impl_ceiling(@root, key)
|
74
|
+
return unless found
|
75
|
+
found.key
|
76
|
+
end
|
77
|
+
|
78
|
+
def select(integer)
|
79
|
+
return if integer < 0 || integer >= size
|
80
|
+
found = impl_select(@root, integer)
|
81
|
+
found.key
|
82
|
+
end
|
83
|
+
|
84
|
+
def rank(key)
|
85
|
+
assert_key_type(key)
|
86
|
+
return unless key
|
87
|
+
impl_rank @root, key
|
88
|
+
end
|
89
|
+
|
90
|
+
def size_consistent?
|
91
|
+
impl_size_consistent?(@root)
|
92
|
+
end
|
93
|
+
|
94
|
+
def rank_consistent?
|
95
|
+
size.times do |time|
|
96
|
+
break false unless time != rank(select(time))
|
97
|
+
end
|
98
|
+
keys.each do |key|
|
99
|
+
comparison = key <=> select(rank(key))
|
100
|
+
break false if comparison != 0
|
101
|
+
end
|
102
|
+
true
|
103
|
+
end
|
104
|
+
|
105
|
+
def symmetric_ordered?
|
106
|
+
impl_symmetric_ordered? @root
|
107
|
+
end
|
108
|
+
|
109
|
+
def keys(low = min, high = max)
|
110
|
+
queue = Algorithmable::DataStructs::Queue.new
|
111
|
+
impl_keys @root, queue, low, high
|
112
|
+
queue
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def check_tree_consistency
|
118
|
+
$stderr.puts 'Tree is not in symmetric order' unless a = symmetric_ordered?
|
119
|
+
$stderr.puts 'Tree has size inconsistency' unless b = size_consistent?
|
120
|
+
$stderr.puts 'Tree has ranking inconsistency' unless c = rank_consistent?
|
121
|
+
a && b && c
|
122
|
+
end
|
123
|
+
|
124
|
+
def impl_symmetric_ordered?(node, min_key = nil, max_key = nil)
|
125
|
+
return true unless node
|
126
|
+
return false if !min_key.nil? && (node.key <=> min_key) <= 0
|
127
|
+
return false if !max_key.nil? && (node.key <=> max_key) >= 0
|
128
|
+
impl_symmetric_ordered?(node.left, min_key, node.key) && impl_symmetric_ordered?(node.right, node.key, max_key)
|
129
|
+
end
|
130
|
+
|
131
|
+
def impl_keys(node, queue, low, high)
|
132
|
+
return unless node
|
133
|
+
cmp_low = low <=> node.key
|
134
|
+
cmp_high = high <=> node.key
|
135
|
+
impl_keys(node.left, queue, low, high) if cmp_low < 0
|
136
|
+
queue.enqueue node.key if cmp_low <= 0 && cmp_high >= 0
|
137
|
+
impl_keys(node.right, queue, low, high) if cmp_high > 0
|
138
|
+
end
|
139
|
+
|
140
|
+
def impl_size_consistent?(node)
|
141
|
+
return true unless node
|
142
|
+
return false if (node.size != node_size(node.left) + node_size(node.right) + 1)
|
143
|
+
impl_size_consistent?(node.left) && impl_size_consistent?(node.right)
|
144
|
+
end
|
145
|
+
|
146
|
+
def assert_value_type(value)
|
147
|
+
fail "Type expectation not met. Use value type `#{@value_type}` instead." unless value.is_a? @value_type
|
148
|
+
end
|
149
|
+
|
150
|
+
def assert_key_type(key)
|
151
|
+
fail "Type expectation not met. Use key type `#{@key_type}` instead." unless key.is_a? @key_type
|
152
|
+
end
|
153
|
+
|
154
|
+
def impl_rank(node, key)
|
155
|
+
return 0 unless node
|
156
|
+
comparison = key <=> node.key
|
157
|
+
if comparison < 0
|
158
|
+
impl_rank(node.left, key)
|
159
|
+
elsif comparison > 0
|
160
|
+
1 + node_size(node.left) + impl_rank(node.right, key)
|
161
|
+
else
|
162
|
+
node_size node.left
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def impl_select(node, index)
|
167
|
+
return unless node
|
168
|
+
left_size = node_size(node.left)
|
169
|
+
if left_size > index
|
170
|
+
impl_select(node.left, index)
|
171
|
+
elsif left_size < index
|
172
|
+
impl_select node.right, (index - left_size - 1)
|
173
|
+
else
|
174
|
+
node
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def impl_ceiling(node, key)
|
179
|
+
return unless node
|
180
|
+
comparison = key <=> node.key
|
181
|
+
return node if 0 == comparison
|
182
|
+
if comparison < 0
|
183
|
+
found = impl_ceiling(node.left, key)
|
184
|
+
return found if found
|
185
|
+
return node
|
186
|
+
end
|
187
|
+
impl_ceiling node.right, key
|
188
|
+
end
|
189
|
+
|
190
|
+
def impl_floor(node, key)
|
191
|
+
return unless node
|
192
|
+
comparison = key <=> node.key
|
193
|
+
return node if 0 == comparison
|
194
|
+
return impl_floor(node.left, key) if comparison < 0
|
195
|
+
found = impl_floor(node.right, key)
|
196
|
+
return found if found
|
197
|
+
node
|
198
|
+
end
|
199
|
+
|
200
|
+
def impl_delete(node, key)
|
201
|
+
return unless node
|
202
|
+
comparison = key <=> node.key
|
203
|
+
if comparison < 0
|
204
|
+
node.left = impl_delete(node.left, key)
|
205
|
+
elsif comparison > 0
|
206
|
+
node.right = impl_delete(node.right, key)
|
207
|
+
else
|
208
|
+
return node.right if node.left.nil?
|
209
|
+
return node.left if node.right.nil?
|
210
|
+
temp = node
|
211
|
+
node = impl_min(temp.right)
|
212
|
+
node.right = impl_delete_min(temp.right)
|
213
|
+
node.left = temp.left
|
214
|
+
end
|
215
|
+
node.size = computed_node_size(node)
|
216
|
+
node
|
217
|
+
end
|
218
|
+
|
219
|
+
def impl_max(node)
|
220
|
+
return node unless node.right
|
221
|
+
impl_max node.right
|
222
|
+
end
|
223
|
+
|
224
|
+
def impl_min(node)
|
225
|
+
return node unless node.left
|
226
|
+
impl_min node.left
|
227
|
+
end
|
228
|
+
|
229
|
+
def impl_delete_max(node)
|
230
|
+
return node.left unless node.right
|
231
|
+
node.right = impl_delete_max(node.right)
|
232
|
+
node.size = computed_node_size(node)
|
233
|
+
node
|
234
|
+
end
|
235
|
+
|
236
|
+
def impl_delete_min(node)
|
237
|
+
return node.right unless node.left
|
238
|
+
node.left = impl_delete_min(node.left)
|
239
|
+
node.size = computed_node_size(node)
|
240
|
+
node
|
241
|
+
end
|
242
|
+
|
243
|
+
def impl_put(node, key, value)
|
244
|
+
return Node.new(key, value, 1) unless node
|
245
|
+
comparison = key <=> node.key
|
246
|
+
if comparison < 0
|
247
|
+
node.left = impl_put(node.left, key, value)
|
248
|
+
elsif comparison > 0
|
249
|
+
node.right = impl_put(node.right, key, value)
|
250
|
+
else
|
251
|
+
node.value = value
|
252
|
+
end
|
253
|
+
node.size = computed_node_size(node)
|
254
|
+
node
|
255
|
+
end
|
256
|
+
|
257
|
+
def impl_get(node, key)
|
258
|
+
return unless node
|
259
|
+
comparison = key <=> node.key
|
260
|
+
if comparison < 0
|
261
|
+
impl_get(node.left, key)
|
262
|
+
elsif comparison > 0
|
263
|
+
impl_get(node.right, key)
|
264
|
+
else
|
265
|
+
node.value
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def node_size(node)
|
270
|
+
node.nil? ? 0 : node.size
|
271
|
+
end
|
272
|
+
|
273
|
+
def computed_node_size(node)
|
274
|
+
1 + node_size(node.left) + node_size(node.right)
|
275
|
+
end
|
276
|
+
|
277
|
+
class Node
|
278
|
+
attr_accessor :key, :value, :left, :right, :size
|
279
|
+
|
280
|
+
def initialize(key = nil, value = nil, size = 0)
|
281
|
+
@key = key
|
282
|
+
@value = value
|
283
|
+
@left = nil
|
284
|
+
@right = nil
|
285
|
+
@size = size
|
286
|
+
end
|
287
|
+
end
|
288
|
+
private_constant :Node
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Searches
|
3
|
+
autoload :BinarySearch, 'algorithmable/search/binary_search'
|
4
|
+
autoload :BinarySearchTree, 'algorithmable/search/binary_search_tree'
|
5
|
+
|
6
|
+
def binary_search(element, collection)
|
7
|
+
BinarySearch.lookup(element, collection)
|
8
|
+
end
|
9
|
+
|
10
|
+
def new_binary_search_tree(key_type, value_type)
|
11
|
+
BinarySearchTree.new key_type, value_type
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/algorithmable.rb
CHANGED
@@ -7,7 +7,7 @@ require 'English'
|
|
7
7
|
module Algorithmable
|
8
8
|
autoload :Errors, 'algorithmable/errors'
|
9
9
|
autoload :Sort, 'algorithmable/sort'
|
10
|
-
autoload :
|
10
|
+
autoload :Searches, 'algorithmable/searches'
|
11
11
|
autoload :DataStructs, 'algorithmable/data_structs'
|
12
12
|
autoload :Graphs, 'algorithmable/graphs'
|
13
13
|
autoload :Puzzles, 'algorithmable/puzzles'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: algorithmable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roman Lishtaba
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -157,8 +157,9 @@ files:
|
|
157
157
|
- lib/algorithmable/puzzles.rb
|
158
158
|
- lib/algorithmable/puzzles/dijkstras_two_stacks.rb
|
159
159
|
- lib/algorithmable/puzzles/josephus_problem.rb
|
160
|
-
- lib/algorithmable/search.rb
|
161
|
-
- lib/algorithmable/search/
|
160
|
+
- lib/algorithmable/search/binary_search.rb
|
161
|
+
- lib/algorithmable/search/binary_search_tree.rb
|
162
|
+
- lib/algorithmable/searches.rb
|
162
163
|
- lib/algorithmable/sort.rb
|
163
164
|
- lib/algorithmable/sort/binary_heap.rb
|
164
165
|
- lib/algorithmable/sort/bubble.rb
|