algorithms 0.0.1 → 0.1.0

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