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 +1,4 @@
1
1
  require 'mkmf'
2
- extension_name = "CPriorityQueue"
2
+ extension_name = "CBst"
3
3
  dir_config(extension_name)
4
4
  create_makefile(extension_name)
@@ -0,0 +1,233 @@
1
+ #include "ruby.h"
2
+
3
+ #define FALSE 0
4
+ #define TRUE 1
5
+
6
+ typedef struct struct_deque_node {
7
+ VALUE obj;
8
+ struct struct_deque_node *left;
9
+ struct struct_deque_node *right;
10
+ } deque_node;
11
+
12
+ typedef struct {
13
+ unsigned int size;
14
+ deque_node *front;
15
+ deque_node *back;
16
+ } deque;
17
+
18
+ void free_nodes(deque_node *node) {
19
+ deque_node *next;
20
+ while(node) {
21
+ next = node->right;
22
+ free(node);
23
+ node = next;
24
+ }
25
+ return;
26
+ }
27
+
28
+ void clear_deque(deque *a_deque) {
29
+ if(a_deque->front)
30
+ free_nodes(a_deque->front);
31
+ a_deque->size = 0;
32
+ a_deque->front = NULL;
33
+ a_deque->back = NULL;
34
+ return;
35
+ }
36
+
37
+ static deque* get_deque_from_self(VALUE self) {
38
+ deque *a_deque;
39
+ Data_Get_Struct(self, deque, a_deque);
40
+ return a_deque;
41
+ }
42
+
43
+ static deque* create_deque() {
44
+ deque *a_deque = ALLOC(deque);
45
+ a_deque->size = 0;
46
+ a_deque->front = NULL;
47
+ a_deque->back = NULL;
48
+ return a_deque;
49
+ }
50
+
51
+ static deque_node* create_node(VALUE obj) {
52
+ deque_node *node = ALLOC(deque_node);
53
+ node->obj = obj;
54
+ node->left = NULL;
55
+ node->right = NULL;
56
+ return node;
57
+ }
58
+
59
+ static void deque_free(deque *deque) {
60
+ free_nodes(deque->front);
61
+ free(deque);
62
+ }
63
+
64
+ static VALUE deque_alloc(VALUE klass) {
65
+ deque *deque = create_deque();
66
+ return Data_Wrap_Struct(klass, NULL, deque_free, deque);
67
+ }
68
+
69
+ static VALUE deque_push_front(VALUE self, VALUE obj) {
70
+ deque *deque = get_deque_from_self(self);
71
+ deque_node *node = create_node(obj);
72
+ if(deque->front) {
73
+ node->right = deque->front;
74
+ deque->front->left = node;
75
+ deque->front = node;
76
+ }
77
+ else {
78
+ deque->front = node;
79
+ deque->back = node;
80
+ }
81
+ deque->size++;
82
+ return obj;
83
+ }
84
+
85
+ static VALUE deque_push_back(VALUE self, VALUE obj) {
86
+ deque *deque = get_deque_from_self(self);
87
+ deque_node *node = create_node(obj);
88
+ if(deque->back) {
89
+ node->left = deque->back;
90
+ deque->back->right = node;
91
+ deque->back = node;
92
+ }
93
+ else {
94
+ deque->front = node;
95
+ deque->back = node;
96
+ }
97
+ deque->size++;
98
+ return obj;
99
+ }
100
+
101
+ static VALUE deque_pop_front(VALUE self) {
102
+ deque *deque = get_deque_from_self(self);
103
+ VALUE obj;
104
+ if(!deque->front)
105
+ return Qnil;
106
+ deque_node *node = deque->front;
107
+ obj = node->obj;
108
+ if(deque->size == 1) {
109
+ clear_deque(deque);
110
+ return obj;
111
+ }
112
+ deque->front->right->left = NULL;
113
+ deque->front = deque->front->right;
114
+ deque->size--;
115
+ return obj;
116
+ }
117
+
118
+ static VALUE deque_front(VALUE self) {
119
+ deque *deque = get_deque_from_self(self);
120
+ if(deque->front)
121
+ return deque->front->obj;
122
+
123
+ return Qnil;
124
+ }
125
+
126
+ static VALUE deque_back(VALUE self) {
127
+ deque *deque = get_deque_from_self(self);
128
+ if(deque->back)
129
+ return deque->back->obj;
130
+
131
+ return Qnil;
132
+ }
133
+
134
+ static VALUE deque_pop_back(VALUE self) {
135
+ deque *deque = get_deque_from_self(self);
136
+ VALUE obj;
137
+ if(!deque->back)
138
+ return Qnil;
139
+ deque_node *node = deque->back;
140
+ obj = node->obj;
141
+ if(deque->size == 1) {
142
+ clear_deque(deque);
143
+ return obj;
144
+ }
145
+ deque->back->left->right = NULL;
146
+ deque->back = deque->back->left;
147
+ deque->size--;
148
+ return obj;
149
+ }
150
+
151
+ static VALUE deque_clear(VALUE self) {
152
+ deque *deque = get_deque_from_self(self);
153
+ clear_deque(deque);
154
+ return Qnil;
155
+ }
156
+
157
+ static VALUE deque_size(VALUE self) {
158
+ deque *deque = get_deque_from_self(self);
159
+ return INT2NUM(deque->size);
160
+ }
161
+
162
+ static VALUE deque_is_empty(VALUE self) {
163
+ deque *deque = get_deque_from_self(self);
164
+ return (deque->size == 0) ? Qtrue : Qfalse;
165
+ }
166
+
167
+ static VALUE deque_each_forward(VALUE self) {
168
+ deque *deque = get_deque_from_self(self);
169
+ deque_node *node = deque->front;
170
+ while(node) {
171
+ rb_yield(node->obj);
172
+ node = node->right;
173
+ }
174
+ return self;
175
+ }
176
+
177
+ static VALUE deque_each_backward(VALUE self) {
178
+ deque *deque = get_deque_from_self(self);
179
+ deque_node *node = deque->back;
180
+ while(node) {
181
+ rb_yield(node->obj);
182
+ node = node->left;
183
+ }
184
+ return self;
185
+ }
186
+
187
+ static VALUE deque_init(int argc, VALUE *argv, VALUE self)
188
+ {
189
+ int len, i;
190
+ VALUE ary;
191
+
192
+ if(argc == 0) {
193
+ return self;
194
+ }
195
+ else if(argc > 1) {
196
+ rb_raise(rb_eArgError, "wrong number of arguments");
197
+ }
198
+ else {
199
+ ary = rb_check_array_type(argv[0]);
200
+ if(!NIL_P(ary)) {
201
+ len = RARRAY_LEN(ary);
202
+ for (i = 0; i < len; i++) {
203
+ deque_push_back(self, RARRAY_PTR(ary)[i]);
204
+ }
205
+ }
206
+ }
207
+ return self;
208
+ }
209
+
210
+ static VALUE cDeque;
211
+ static VALUE mContainers;
212
+
213
+ void Init_CDeque() {
214
+ mContainers = rb_define_module("Containers");
215
+ cDeque = rb_define_class_under(mContainers, "CDeque", rb_cObject);
216
+ rb_define_alloc_func(cDeque, deque_alloc);
217
+ rb_define_method(cDeque, "initialize", deque_init, -1);
218
+ rb_define_method(cDeque, "push_front", deque_push_front, 1);
219
+ rb_define_method(cDeque, "push_back", deque_push_back, 1);
220
+ rb_define_method(cDeque, "clear", deque_clear, 0);
221
+ rb_define_method(cDeque, "front", deque_front, 0);
222
+ rb_define_method(cDeque, "back", deque_back, 0);
223
+ rb_define_method(cDeque, "pop_front", deque_pop_front, 0);
224
+ rb_define_method(cDeque, "pop_back", deque_pop_back, 0);
225
+ rb_define_method(cDeque, "size", deque_size, 0);
226
+ rb_define_alias(cDeque, "length", "size");
227
+ rb_define_method(cDeque, "empty?", deque_is_empty, 0);
228
+ rb_define_method(cDeque, "each_forward", deque_each_forward, 0);
229
+ rb_define_method(cDeque, "each_backward", deque_each_backward, 0);
230
+ rb_define_alias(cDeque, "each", "each_forward");
231
+ rb_define_alias(cDeque, "reverse_each", "each_backward");
232
+ rb_include_module(cDeque, rb_eval_string("Enumerable"));
233
+ }
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ extension_name = "CDeque"
3
+ dir_config(extension_name)
4
+ create_makefile(extension_name)
@@ -1,4 +1,4 @@
1
1
  require 'mkmf'
2
- extension_name = "CTreeMap"
2
+ extension_name = "CRBTreeMap"
3
3
  dir_config(extension_name)
4
4
  create_makefile(extension_name)
@@ -122,6 +122,7 @@ static rbtree_node* fixup(rbtree_node *h) {
122
122
 
123
123
  return set_num_nodes(h);
124
124
  }
125
+
125
126
  static rbtree* create_rbtree(int (*compare_function)(VALUE, VALUE)) {
126
127
  rbtree *tree = ALLOC(rbtree);
127
128
  tree->black_height = 0;
@@ -146,11 +147,6 @@ static rbtree_node* insert(rbtree *tree, rbtree_node *node, VALUE key, VALUE val
146
147
  return new_node;
147
148
  }
148
149
 
149
- // Do a top-down breaking of 4-nodes
150
- if ( isred(node->left) && isred(node->right) ) {
151
- colorflip(node);
152
- }
153
-
154
150
  // Insert left or right, recursively
155
151
  cmp = tree->compare_function(key, node->key);
156
152
  if (cmp == 0) { node->value = value; }
@@ -160,7 +156,9 @@ static rbtree_node* insert(rbtree *tree, rbtree_node *node, VALUE key, VALUE val
160
156
  // Fix our tree to keep left-lean
161
157
  if (isred(node->right)) { node = rotate_left(node); }
162
158
  if (isred(node->left) && isred(node->left->left)) { node = rotate_right(node); }
163
-
159
+ if ( isred(node->left) && isred(node->right) ) {
160
+ colorflip(node);
161
+ }
164
162
  return set_num_nodes(node);
165
163
  }
166
164
 
@@ -191,34 +189,40 @@ static VALUE max_key(rbtree_node *node) {
191
189
  return max_key(node->right);
192
190
  }
193
191
 
194
- static rbtree_node* delete_min(rbtree_node *h) {
195
- if ( !(h->left) )
192
+ static rbtree_node* delete_min(rbtree_node *h, VALUE *deleted_value) {
193
+ if ( !h->left ) {
194
+ if(deleted_value)
195
+ *deleted_value = h->value;
196
+ free(h);
196
197
  return NULL;
198
+ }
197
199
 
198
200
  if ( !isred(h->left) && !isred(h->left->left) )
199
201
  h = move_red_left(h);
200
202
 
201
- h->left = delete_min(h->left);
203
+ h->left = delete_min(h->left, deleted_value);
202
204
 
203
205
  return fixup(h);
204
206
  }
205
207
 
206
- static rbtree_node* delete_max(rbtree_node *h) {
208
+ static rbtree_node* delete_max(rbtree_node *h, VALUE *deleted_value) {
207
209
  if ( isred(h->left) )
208
210
  h = rotate_right(h);
209
211
 
210
- if ( !(h->right) )
212
+ if ( !h->right ) {
213
+ *deleted_value = h->value;
214
+ free(h);
211
215
  return NULL;
216
+ }
212
217
 
213
218
  if ( !isred(h->right) && !isred(h->right->left) )
214
219
  h = move_red_right(h);
215
220
 
216
- h->right = delete_max(h->right);
221
+ h->right = delete_max(h->right, deleted_value);
217
222
 
218
223
  return fixup(h);
219
224
  }
220
225
 
221
-
222
226
  static rbtree_node* delete(rbtree *tree, rbtree_node *node, VALUE key, VALUE *deleted_value) {
223
227
  int cmp;
224
228
  VALUE minimum_key;
@@ -232,9 +236,11 @@ static rbtree_node* delete(rbtree *tree, rbtree_node *node, VALUE key, VALUE *de
232
236
  else {
233
237
  if ( isred(node->left) )
234
238
  node = rotate_right(node);
235
-
236
- if ( (cmp == 0) && !(node->right) ) {
239
+
240
+ cmp = tree->compare_function(key, node->key);
241
+ if ( (cmp == 0) && !node->right ) {
237
242
  *deleted_value = node->value;
243
+ free(node);
238
244
  return NULL;
239
245
  }
240
246
 
@@ -247,7 +253,7 @@ static rbtree_node* delete(rbtree *tree, rbtree_node *node, VALUE key, VALUE *de
247
253
  minimum_key = min_key(node->right);
248
254
  node->value = get(tree, node->right, minimum_key);
249
255
  node->key = minimum_key;
250
- node->right = delete_min(node->right);
256
+ node->right = delete_min(node->right, NULL);
251
257
  }
252
258
  else {
253
259
  node->right = delete(tree, node->right, key, deleted_value);
@@ -273,7 +279,6 @@ static rbtree* rbt_each(rbtree *tree, void (*each)(rbtree *tree, rbtree_node *no
273
279
  rbtree_each_node(tree, tree->root, each, arguments);
274
280
  return tree;
275
281
  }
276
-
277
282
 
278
283
  // Methods to be called in Ruby
279
284
 
@@ -298,7 +303,7 @@ static VALUE rbtree_alloc(VALUE klass) {
298
303
  return Data_Wrap_Struct(klass, NULL, rbtree_free, tree);
299
304
  }
300
305
 
301
- static VALUE rbtree_put(VALUE self, VALUE key, VALUE value) {
306
+ static VALUE rbtree_push(VALUE self, VALUE key, VALUE value) {
302
307
  rbtree *tree = get_tree_from_self(self);
303
308
  tree->root = insert(tree, tree->root, key, value);
304
309
  return value;
@@ -314,13 +319,19 @@ static VALUE rbtree_size(VALUE self) {
314
319
  return INT2NUM(size(tree->root));
315
320
  }
316
321
 
322
+ static VALUE rbtree_is_empty(VALUE self) {
323
+ rbtree *tree = get_tree_from_self(self);
324
+ return (tree->root ? Qfalse : Qtrue);
325
+ }
326
+
317
327
  static VALUE rbtree_height(VALUE self) {
318
328
  rbtree *tree = get_tree_from_self(self);
319
329
  return INT2NUM(height(tree->root));
320
330
  }
321
331
 
322
- static VALUE rbtree_contains(VALUE self, VALUE key) {
332
+ static VALUE rbtree_has_key(VALUE self, VALUE key) {
323
333
  rbtree *tree = get_tree_from_self(self);
334
+ if(!tree->root) { return Qfalse; }
324
335
  if(get(tree, tree->root, key) == Qnil)
325
336
  return Qfalse;
326
337
 
@@ -350,7 +361,41 @@ static VALUE rbtree_delete(VALUE self, VALUE key) {
350
361
  return Qnil;
351
362
 
352
363
  tree->root = delete(tree, tree->root, key, &deleted_value);
364
+ if(tree->root)
365
+ tree->root->color = BLACK;
366
+
367
+ if(deleted_value) {
368
+ return deleted_value;
369
+ }
370
+
371
+ return Qnil;
372
+ }
373
+
374
+ static VALUE rbtree_delete_min(VALUE self) {
375
+ VALUE deleted_value;
376
+ rbtree *tree = get_tree_from_self(self);
353
377
  if(!tree->root)
378
+ return Qnil;
379
+
380
+ tree->root = delete_min(tree->root, &deleted_value);
381
+ if(tree->root)
382
+ tree->root->color = BLACK;
383
+
384
+ if(deleted_value) {
385
+ return deleted_value;
386
+ }
387
+
388
+ return Qnil;
389
+ }
390
+
391
+ static VALUE rbtree_delete_max(VALUE self) {
392
+ VALUE deleted_value;
393
+ rbtree *tree = get_tree_from_self(self);
394
+ if(!tree->root)
395
+ return Qnil;
396
+
397
+ tree->root = delete_max(tree->root, &deleted_value);
398
+ if(tree->root)
354
399
  tree->root->color = BLACK;
355
400
 
356
401
  if(deleted_value) {
@@ -373,23 +418,26 @@ static VALUE rbtree_each(VALUE self) {
373
418
  static VALUE cRBTree;
374
419
  static VALUE mContainers;
375
420
 
376
- void Init_CTreeMap() {
421
+ void Init_CRBTreeMap() {
377
422
  id_compare_operator = rb_intern("<=>");
378
423
 
379
424
  mContainers = rb_define_module("Containers");
380
- cRBTree = rb_define_class_under(mContainers, "CTreeMap", rb_cObject);
425
+ cRBTree = rb_define_class_under(mContainers, "CRBTreeMap", rb_cObject);
381
426
  rb_define_alloc_func(cRBTree, rbtree_alloc);
382
427
  rb_define_method(cRBTree, "initialize", rbtree_init, 0);
383
- rb_define_method(cRBTree, "put", rbtree_put, 2);
384
- rb_define_alias(cRBTree, "[]=", "put");
428
+ rb_define_method(cRBTree, "push", rbtree_push, 2);
429
+ rb_define_alias(cRBTree, "[]=", "push");
385
430
  rb_define_method(cRBTree, "size", rbtree_size, 0);
431
+ rb_define_method(cRBTree, "empty?", rbtree_is_empty, 0);
386
432
  rb_define_method(cRBTree, "height", rbtree_height, 0);
387
433
  rb_define_method(cRBTree, "min_key", rbtree_min_key, 0);
388
434
  rb_define_method(cRBTree, "max_key", rbtree_max_key, 0);
435
+ rb_define_method(cRBTree, "delete_min", rbtree_delete_min, 0);
436
+ rb_define_method(cRBTree, "delete_max", rbtree_delete_max, 0);
389
437
  rb_define_method(cRBTree, "each", rbtree_each, 0);
390
438
  rb_define_method(cRBTree, "get", rbtree_get, 1);
391
439
  rb_define_alias(cRBTree, "[]", "get");
392
- rb_define_method(cRBTree, "contains?", rbtree_contains, 1);
440
+ rb_define_method(cRBTree, "has_key?", rbtree_has_key, 1);
393
441
  rb_define_method(cRBTree, "delete", rbtree_delete, 1);
394
442
  rb_include_module(cRBTree, rb_eval_string("Enumerable"));
395
- }
443
+ }