algorithmable 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|