algorithms 0.0.1 → 0.1.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.
Files changed (54) hide show
  1. data/History.txt +139 -2
  2. data/Manifest +31 -8
  3. data/README +90 -0
  4. data/Rakefile +22 -9
  5. data/algorithms.gemspec +28 -101
  6. data/benchmark.rb +29 -27
  7. data/benchmarks/rbench.rb +16 -0
  8. data/benchmarks/rbench/column.rb +26 -0
  9. data/benchmarks/rbench/group.rb +43 -0
  10. data/benchmarks/rbench/report.rb +53 -0
  11. data/benchmarks/rbench/runner.rb +109 -0
  12. data/benchmarks/rbench/summary.rb +51 -0
  13. data/benchmarks/sorts.rb +33 -0
  14. data/ext/containers/bst/bst.c +205 -0
  15. data/ext/containers/{priority_queue → bst}/extconf.rb +1 -1
  16. data/ext/containers/deque/deque.c +233 -0
  17. data/ext/containers/deque/extconf.rb +4 -0
  18. data/ext/containers/tree_map/extconf.rb +1 -1
  19. data/ext/containers/tree_map/rbtree.c +73 -25
  20. data/lib/algorithms.rb +65 -6
  21. data/lib/algorithms/search.rb +84 -0
  22. data/lib/algorithms/sort.rb +238 -0
  23. data/lib/containers/deque.rb +176 -0
  24. data/lib/containers/heap.rb +451 -111
  25. data/lib/containers/kd_tree.rb +87 -0
  26. data/lib/containers/priority_queue.rb +107 -508
  27. data/lib/containers/queue.rb +62 -23
  28. data/lib/containers/rb_tree_map.rb +398 -0
  29. data/lib/containers/splay_tree_map.rb +274 -0
  30. data/lib/containers/stack.rb +59 -21
  31. data/lib/containers/suffix_array.rb +68 -0
  32. data/lib/containers/trie.rb +182 -0
  33. data/lib/graphs/graph.rb +25 -0
  34. data/spec/bst_spec.rb +31 -0
  35. data/spec/deque_spec.rb +108 -0
  36. data/spec/heap_spec.rb +111 -66
  37. data/spec/kd_tree_spec.rb +89 -0
  38. data/spec/priority_queue_spec.rb +71 -27
  39. data/spec/queue_spec.rb +53 -45
  40. data/spec/rb_tree_map_spec.rb +123 -0
  41. data/spec/search_spec.rb +28 -0
  42. data/spec/sort_spec.rb +28 -0
  43. data/spec/splay_tree_map_spec.rb +102 -0
  44. data/spec/stack_spec.rb +56 -49
  45. data/spec/suffix_array_spec.rb +40 -0
  46. data/spec/trie_spec.rb +59 -0
  47. metadata +54 -32
  48. data/README.txt +0 -58
  49. data/ext/containers/priority_queue/priority_queue.c +0 -948
  50. data/ext/containers/tree_map/Rakefile +0 -4
  51. data/lib/containers/hash.rb +0 -0
  52. data/lib/containers/tree_map.rb +0 -265
  53. data/spec/priority_queue_test.rb +0 -371
  54. data/spec/tree_map_spec.rb +0 -99
@@ -1,4 +0,0 @@
1
- task :default do
2
- sh "make"
3
- sh "ruby -e 'require \"c_tree_map\"; puts a = CTreeMap.new; 100.times { |x| a.put(x,x) }; p a.size; p a.get(13); p a.contains?(200)'"
4
- end
File without changes
@@ -1,265 +0,0 @@
1
- module Containers
2
- # A TreeMap implemented with a self-balancing red-black tree
3
- # Adapted from Robert Sedgewick's Left Leaning Red-Black Tree Implementation
4
- # http://www.cs.princeton.edu/~rs/talks/LLRB/Java/RedBlackBST.java
5
- class RubyTreeMap
6
- include Enumerable
7
-
8
- class Node
9
- attr_accessor :color, :key, :value, :left, :right, :num_nodes, :height
10
- def initialize(key, value)
11
- @key = key
12
- @value = value
13
- @color = :red
14
- @left = nil
15
- @right = nil
16
- @num_nodes = 1
17
- @height = 1
18
- end
19
- end
20
-
21
- attr_accessor :height_black
22
-
23
- def initialize
24
- @root = nil
25
- @height_black = 0
26
- end
27
-
28
- def put(key, value)
29
- @root = insert(@root, key, value)
30
- @height_black += 1 if isred(@root)
31
- @root.color = :black
32
- end
33
- alias :[]= :put
34
-
35
- def size
36
- sizeR(@root)
37
- end
38
-
39
- def height
40
- heightR(@root)
41
- end
42
-
43
- def contains?(key)
44
- !get(key).nil?
45
- end
46
-
47
- def get(key)
48
- getR(@root, key)
49
- end
50
- alias :[] :get
51
-
52
- def min_key
53
- @root.nil? ? nil : minR(@root)
54
- end
55
-
56
- def max_key
57
- @root.nil? ? nil : maxR(@root)
58
- end
59
-
60
- def delete(key)
61
- result = nil
62
- if @root
63
- @root, result = deleteR(@root, key)
64
- @root.color = :black
65
- end
66
- result
67
- end
68
-
69
- def each(&block)
70
- @root.nil? ? nil : eachR(@root, block)
71
- end
72
-
73
- def to_s
74
- return "" if @root.nil?
75
- "#{@height_black} #{to_sR(@root)}"
76
- end
77
-
78
- private
79
-
80
- def eachR(node, block)
81
- return if node.nil?
82
-
83
- eachR(node.left, block)
84
- block.call(node.key, node.value)
85
- eachR(node.right, block)
86
- end
87
-
88
- def deleteR(node, key)
89
- if (key <=> node.key) == -1
90
- node = move_red_left(node) if (!isred(node.left) && !isred(node.left.left))
91
- node.left, result = deleteR(node.left, key)
92
- else
93
- node = rotate_right(node) if isred(node.left)
94
- if ( ( (key <=> node.key) == 0) && node.right.nil? )
95
- return nil, node.value
96
- end
97
- if (!isred(node.right) && !isred(node.right.left))
98
- node = move_red_right(node);
99
- end
100
- if (key <=> node.key) == 0
101
- result = node.value
102
- node.value = getR(node.right, minR(node.right))
103
- node.key = minR(node.right)
104
- node.right = delete_minR(node.right)
105
- else
106
- node.right, result = deleteR(node.right, key)
107
- end
108
- end
109
- return fixup(node), result
110
- end
111
-
112
- def delete_minR(node)
113
- return nil if node.left.nil?
114
- if ( !isred(node.left) && !isred(node.left.left) )
115
- node = move_red_left(node)
116
- end
117
- node.left = delete_minR(node.left)
118
-
119
- fixup(node)
120
- end
121
-
122
- def delete_maxR(node)
123
- if (isred(node.left))
124
- node = rotate_right(node)
125
- end
126
- return nil if node.right.nil?
127
- if ( !isred(node.right) && !isred(node.right.left) )
128
- node = move_red_right(node)
129
- end
130
- node.right = delete_maxR(node.right)
131
-
132
- fixup(node)
133
- end
134
-
135
- def getR(node, key)
136
- return nil if node.nil?
137
- case key <=> node.key
138
- when 0 then return node.value;
139
- when -1 then return getR(node.left, key)
140
- when 1 then return getR(node.right, key)
141
- end
142
- end
143
-
144
- def to_sR(x)
145
- s = "("
146
- x.left.nil? ? s << '(' : s << to_sR(x.left)
147
- s << "*" if isred(x)
148
- x.right.nil? ? s << ')' : s << to_sR(x.right)
149
- s + ')'
150
- end
151
-
152
- def sizeR(node)
153
- return 0 if node.nil?
154
-
155
- node.num_nodes
156
- end
157
-
158
- def heightR(node)
159
- return 0 if node.nil?
160
-
161
- node.height
162
- end
163
-
164
- def minR(node)
165
- return node.key if node.left.nil?
166
-
167
- minR(node.left)
168
- end
169
-
170
- def maxR(node)
171
- return node.key if node.right.nil?
172
-
173
- maxR(node.right)
174
- end
175
-
176
- def insert(node, key, value)
177
- if(node.nil?)
178
- return Node.new(key, value)
179
- end
180
-
181
- colorflip(node) if (isred(node.left) && isred(node.right))
182
-
183
- case key <=> node.key
184
- when 0 then node.value = value
185
- when -1 then node.left = insert(node.left, key, value)
186
- when 1 then node.right = insert(node.right, key, value)
187
- end
188
-
189
- node = rotate_left(node) if isred(node.right)
190
- node = rotate_right(node) if (isred(node.left) && isred(node.left.left))
191
-
192
- set_num_nodes(node)
193
- end
194
-
195
- def isred(h)
196
- return false if h.nil?
197
-
198
- h.color == :red
199
- end
200
-
201
- def rotate_left(h)
202
- x = h.right
203
- h.right = x.left
204
- x.left = set_num_nodes(h)
205
- x.color = x.left.color
206
- x.left.color = :red
207
-
208
- set_num_nodes(x)
209
- end
210
-
211
- def rotate_right(h)
212
- x = h.left
213
- h.left = x.right
214
- x.right = set_num_nodes(h)
215
- x.color = x.right.color
216
- x.right.color = :red
217
-
218
- set_num_nodes(x);
219
- end
220
-
221
- def colorflip(h)
222
- h.color = h.color == :red ? :black : :red
223
- h.left.color = h.left.color == :red ? :black : :red
224
- h.right.color = h.right.color == :red ? :black : :red
225
- end
226
-
227
- def move_red_left(h)
228
- colorflip(h)
229
- if isred(h.right.left)
230
- h.right = rotate_right(h.right)
231
- h = rotate_left(h)
232
- colorflip(h)
233
- end
234
- h
235
- end
236
-
237
- def move_red_right(h)
238
- colorflip(h)
239
- if isred(h.left.left)
240
- h = rotate_right(h)
241
- colorflip(h)
242
- end
243
- h
244
- end
245
-
246
- def fixup(h)
247
- h = rotate_left(h) if isred(h.right)
248
- h = rotate_right(h) if (isred(h.left) && isred(h.left.left))
249
- colorflip(h) if (isred(h.left) && isred(h.right))
250
-
251
- set_num_nodes(h)
252
- end
253
-
254
- def set_num_nodes(h)
255
- h.num_nodes = sizeR(h.left) + sizeR(h.right) + 1
256
- if heightR(h.left) > heightR(h.right)
257
- h.height = heightR(h.left) + 1
258
- else
259
- h.height = heightR(h.right) + 1
260
- end
261
- h
262
- end
263
- end
264
-
265
- end
@@ -1,371 +0,0 @@
1
- #!/usr/bin/ruby
2
-
3
- # Priority Queue tests
4
-
5
- $:.unshift '../ext/priority_queue/CPriorityQueue'
6
- $:.unshift '../lib/'
7
-
8
- require 'test/unit'
9
-
10
- require 'priority_queue/ruby_priority_queue'
11
- require 'priority_queue/poor_priority_queue'
12
- begin
13
- require 'priority_queue/CPriorityQueue'
14
- rescue LoadError
15
- require 'CPriorityQueue'
16
- end
17
-
18
-
19
- module PriorityQueueTest
20
- # Check that the order is maintained
21
- def teardown
22
- last = @q.min_priority
23
- while priority = @q.delete_min_return_priority
24
- assert_operator(last, :<=, priority)
25
- last = priority
26
- end
27
- end
28
-
29
- def test_length
30
- 20.times do | i |
31
- assert_equal(i, @q.length)
32
- @q[i] = i
33
- end
34
- 10.times do | i |
35
- assert_equal(20-i, @q.length)
36
- @q.delete_min
37
- end
38
- 10.times do | i |
39
- assert_equal(10+i, @q.length)
40
- @q[i] = i
41
- end
42
- @q.delete(5)
43
- assert_equal(19, @q.length)
44
- end
45
-
46
- def test_merge
47
- @q1 = @q.class.new
48
- @q2 = @q.class.new
49
-
50
- 20.times do | i |
51
- @q1[i] = i
52
- @q2[i+20] = i+20
53
- end
54
- end
55
-
56
- # Assure that delete min works
57
- def test_delete_min
58
- assert_equal(nil, @q.delete_min, "Empty queue should pop nil")
59
- @q["n1"] = 0
60
- assert_equal(["n1", 0], @q.delete_min)
61
- @q["n1"] = 0
62
- @q["n2"] = -1
63
- assert_equal(["n2", -1], @q.delete_min)
64
- end
65
-
66
- def test_delete_min_return_key
67
- assert_equal(nil, @q.delete_min_return_key, "Empty queue should pop nil")
68
- @q["n1"] = 0
69
- assert_equal("n1", @q.delete_min_return_key)
70
- @q["n1"] = 0
71
- @q["n2"] = -1
72
- assert_equal("n2", @q.delete_min_return_key)
73
- end
74
-
75
- def test_delete_min_return_priority
76
- assert_equal(nil, @q.delete_min_return_priority, "Empty queue should pop nil")
77
- @q["n1"] = 0
78
- assert_equal(0, @q.delete_min_return_priority)
79
- @q["n1"] = 0
80
- @q["n2"] = -1
81
- assert_equal(-1, @q.delete_min_return_priority)
82
- end
83
-
84
- def test_has_key?
85
- assert(!@q.has_key?(1))
86
- @q[1] = 1
87
- assert(@q.has_key?(1))
88
- end
89
-
90
- def test_empty?
91
- assert_equal(true, @q.empty?, "Empty queue should return true on empty?")
92
- @q["node1"] = 10
93
- assert_equal(false, @q.empty?, "Filled queue should return false on empty?")
94
- end
95
-
96
- def test_push
97
- 20.times do | i |
98
- @q.push i, i+10
99
- end
100
-
101
- 20.times do | i |
102
- @q.push i, i
103
- end
104
-
105
- 20.times do | i |
106
- assert_equal([i, i], @q.delete_min)
107
- end
108
-
109
- assert_equal(nil, @q.delete_min)
110
- end
111
-
112
- def test_push_pop
113
- 20.times do | i |
114
- @q.push i, i
115
- end
116
-
117
- 20.times do | i |
118
- assert_equal([i, i], @q.delete_min)
119
- end
120
-
121
- assert_equal(nil, @q.delete_min)
122
- end
123
-
124
- def test_push_decrease_pop
125
- 50.times do | i |
126
- @q.push i, i
127
- end
128
-
129
- 10.times do | i |
130
- assert_equal([i, i], @q.delete_min)
131
- end
132
-
133
- 10.times do | i |
134
- @q[i+10] = i
135
- end
136
-
137
- 10.times do | i |
138
- assert_equal([i+10, i], @q.delete_min)
139
- end
140
-
141
- 30.times do | i |
142
- assert_equal([i+20, i+20], @q.delete_min)
143
- end
144
-
145
- assert_equal(nil, @q.delete_min)
146
- end
147
-
148
- def test_min_key
149
- assert_equal(nil, @q.min_key)
150
- @q["node1"] = 0
151
- assert_equal("node1", @q.min_key)
152
- @q["node2"] = 1
153
- assert_equal("node1", @q.min_key)
154
- @q["node3"] = -1
155
- assert_equal("node3", @q.min_key)
156
- end
157
-
158
- def test_min_priority
159
- assert_equal(nil, @q.min_priority)
160
- @q["node1"] = 0
161
- assert_equal(0, @q.min_priority)
162
- @q["node2"] = 1
163
- assert_equal(0, @q.min_priority)
164
- @q["node3"] = -1
165
- assert_equal(-1, @q.min_priority)
166
- end
167
-
168
- def test_access
169
- assert_equal(0, @q["node1"] = 0)
170
- assert_equal(["node1", 0], @q.min)
171
- assert_equal(1, @q["node2"] = 1)
172
- assert_equal(1, @q["node2"])
173
- assert_equal("node1", @q.min_key)
174
- assert_equal(2, @q["node3"] = 2)
175
- assert_equal(2, @q["node3"])
176
- assert_equal("node1", @q.min_key)
177
- assert_equal(-1, @q["node3"] = -1)
178
- assert_equal(-1, @q["node3"])
179
- assert_equal("node3", @q.min_key)
180
- end
181
-
182
- def test_min
183
- assert_equal(nil, @q.min)
184
- @q["node1"] = 10
185
- assert_equal(["node1", 10], @q.min)
186
- @q["node2"] = 5
187
- assert_equal(["node2", 5], @q.min)
188
- end
189
-
190
- def test_decrease_priority
191
-
192
- 20.times do | i |
193
- @q.push i, i / 20.0
194
- end
195
-
196
- assert_equal([0, 0], @q.delete_min)
197
-
198
- @q[10] = -1
199
- @q[11] = -0.5
200
-
201
- [10, 11, (1..9).to_a, (12..19).to_a, nil].flatten.each do | shall |
202
- key, priority = *@q.delete_min
203
- assert_equal(shall, key)
204
- end
205
- end
206
-
207
- def test_increase_priority
208
- 20.times do | i |
209
- @q[i] = i
210
- end
211
- @q[10] = 5
212
- assert_equal([0,0], @q.delete_min)
213
- assert_equal(10, @q[10] = 10)
214
- assert_equal(20, @q[11] = 20)
215
- assert_equal([1,1], @q.delete_min)
216
- end
217
-
218
- def test_delete
219
- @q[1] = 1
220
- @q[2] = 2
221
- @q[3] = 3
222
- assert_equal(1, @q[1])
223
- assert_equal([1,1], @q.min)
224
- assert_equal([1,1], @q.delete(1))
225
- assert_equal(nil, @q[1])
226
- assert_equal([2,2], @q.min)
227
- assert_equal(nil, @q.delete(1))
228
- end
229
-
230
- def test_example_1
231
- assert_equal(0, @q["node1"] = 0)
232
- assert_equal(1, @q["node2"] = 1)
233
- assert_equal("node1", @q.min_key)
234
- assert_equal(0, @q[@q.min_key])
235
- assert_equal(0, @q.min_priority)
236
-
237
- @q["node2"] = -1
238
- assert_equal(["node2", -1], @q.delete_min)
239
- assert_equal(nil, @q["node2"])
240
- @q["node3"] = 1
241
-
242
- assert_equal(["node3", 1], @q.delete("node3"))
243
- assert_equal(nil, @q.delete("node2"))
244
- end
245
-
246
- def test_dup
247
- ('a'..'z').each do | n |
248
- @q[n] = n[0]
249
- end
250
- qq = @q.dup
251
- until @q.empty?
252
- assert_equal(@q.delete_min, qq.delete_min)
253
- end
254
- end
255
-
256
- def test_each
257
- ('a'..'z').each do | n |
258
- @q[n] = n[0]
259
- end
260
- queue = ('a'..'z').inject([]) { | r, n | r << [n, n[0]] }
261
- assert_equal(queue.sort, @q.to_a.sort)
262
- end
263
-
264
- extend self
265
- end
266
-
267
- class CPriorityQueueTest < Test::Unit::TestCase
268
- include PriorityQueueTest
269
-
270
- def setup
271
- @q = CPriorityQueue.new
272
- end
273
-
274
- def test_to_dot
275
- 5.times do | i |
276
- @q.push "N#{i}", i
277
- end
278
- @q.delete_min
279
- assert_equal(
280
- ['digraph fibonacci_heap {',
281
- ' NODE [label="N1 (1)",shape=box];',
282
- ' NODE [label="N3 (3)",shape=box];',
283
- ' NODE [label="N4 (4)",shape=box];',
284
- ' NODE -> NODE;',
285
- ' NODE -> NODE;',
286
- ' NODE [label="N2 (2)",shape=box];',
287
- ' NODE -> NODE;',
288
- '}',''].join("\n"), @q.to_dot.gsub(/NODE[0-9]*/, 'NODE'))
289
- end
290
-
291
- end
292
-
293
- class PoorPriorityQueueTest < Test::Unit::TestCase
294
- include PriorityQueueTest
295
-
296
- def setup
297
- @q = PoorPriorityQueue.new
298
- end
299
-
300
- end
301
-
302
- class RubyPriorityQueueTest < Test::Unit::TestCase
303
- include PriorityQueueTest
304
-
305
- def setup
306
- @q = RubyPriorityQueue.new
307
- end
308
-
309
- def test_private_link_nodes
310
- q = RubyPriorityQueue.new
311
- q[0] = 0
312
- q[1] = 1
313
- tc = self
314
- q.instance_eval do
315
- n0 = @nodes[0]
316
- n1 = @nodes[1]
317
- n0.right = n0.left = n0
318
- n1.right = n1.left = n1
319
- tc.assert_equal(n0, link_nodes(n0, n1))
320
- tc.assert_equal(n0.child, n1)
321
- tc.assert_equal(n1.child, nil)
322
- tc.assert_equal(n0.left, n0)
323
- tc.assert_equal(n1.left, n1)
324
- tc.assert_equal(n0.right, n0)
325
- tc.assert_equal(n1.right, n1)
326
- end
327
- q = RubyPriorityQueue.new
328
- q[0] = 0
329
- q[1] = 1
330
- q.instance_eval do
331
- n0 = @nodes[0]
332
- n1 = @nodes[1]
333
- n0.right = n0.left = n0
334
- n1.right = n1.left = n1
335
- tc.assert_equal(n0, link_nodes(n1, n0))
336
- tc.assert_equal(n0.child, n1)
337
- tc.assert_equal(n1.child, nil)
338
- tc.assert_equal(n0.left, n0)
339
- tc.assert_equal(n1.left, n1)
340
- tc.assert_equal(n0.right, n0)
341
- tc.assert_equal(n1.right, n1)
342
- end
343
- end
344
-
345
-
346
- def test_private_delete_first
347
- q = RubyPriorityQueue.new
348
- q[0] = 0
349
- q[1] = 1
350
- q[2] = 2
351
- tc = self
352
- q.instance_eval do
353
- 2.times do
354
- r = @rootlist
355
- tc.assert_equal(r, delete_first)
356
- tc.assert_equal(r.right, r)
357
- tc.assert_equal(r.left, r)
358
- tc.assert_not_equal(r, @rootlist.left)
359
- tc.assert_not_equal(r, @rootlist.right)
360
- end
361
- r = @rootlist
362
- tc.assert_equal(r, delete_first)
363
- tc.assert_equal(r.right, r)
364
- tc.assert_equal(r.left, r)
365
- tc.assert_equal(nil, @rootlist)
366
-
367
- tc.assert_equal(nil, delete_first)
368
- end
369
- end
370
- end
371
-