grosser-algorithms 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/History.txt +176 -0
  2. data/Manifest +47 -0
  3. data/README.markdown +102 -0
  4. data/Rakefile +26 -0
  5. data/algorithms.gemspec +32 -0
  6. data/benchmarks/deque.rb +18 -0
  7. data/benchmarks/sorts.rb +34 -0
  8. data/benchmarks/treemaps.rb +52 -0
  9. data/ext/algorithms/string/extconf.rb +4 -0
  10. data/ext/algorithms/string/string.c +70 -0
  11. data/ext/containers/deque/deque.c +249 -0
  12. data/ext/containers/deque/extconf.rb +4 -0
  13. data/ext/containers/rbtree_map/extconf.rb +4 -0
  14. data/ext/containers/rbtree_map/rbtree.c +500 -0
  15. data/ext/containers/splaytree_map/extconf.rb +4 -0
  16. data/ext/containers/splaytree_map/splaytree.c +421 -0
  17. data/grosser-algorithms.gemspec +31 -0
  18. data/lib/algorithms.rb +71 -0
  19. data/lib/algorithms/search.rb +86 -0
  20. data/lib/algorithms/sort.rb +243 -0
  21. data/lib/algorithms/string.rb +8 -0
  22. data/lib/containers/deque.rb +176 -0
  23. data/lib/containers/heap.rb +507 -0
  24. data/lib/containers/kd_tree.rb +113 -0
  25. data/lib/containers/priority_queue.rb +117 -0
  26. data/lib/containers/queue.rb +72 -0
  27. data/lib/containers/rb_tree_map.rb +402 -0
  28. data/lib/containers/splay_tree_map.rb +273 -0
  29. data/lib/containers/stack.rb +71 -0
  30. data/lib/containers/suffix_array.rb +72 -0
  31. data/lib/containers/trie.rb +188 -0
  32. data/spec/deque_gc_mark_spec.rb +18 -0
  33. data/spec/deque_spec.rb +108 -0
  34. data/spec/heap_spec.rb +126 -0
  35. data/spec/kd_expected_out.txt +10000 -0
  36. data/spec/kd_test_in.txt +10000 -0
  37. data/spec/kd_tree_spec.rb +34 -0
  38. data/spec/map_gc_mark_spec.rb +29 -0
  39. data/spec/priority_queue_spec.rb +75 -0
  40. data/spec/queue_spec.rb +61 -0
  41. data/spec/rb_tree_map_spec.rb +122 -0
  42. data/spec/search_spec.rb +28 -0
  43. data/spec/sort_spec.rb +27 -0
  44. data/spec/splay_tree_map_spec.rb +106 -0
  45. data/spec/stack_spec.rb +60 -0
  46. data/spec/string_spec.rb +13 -0
  47. data/spec/suffix_array_spec.rb +40 -0
  48. data/spec/trie_spec.rb +59 -0
  49. metadata +141 -0
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ extension_name = "CSplayTreeMap"
3
+ dir_config(extension_name)
4
+ create_makefile(extension_name)
@@ -0,0 +1,421 @@
1
+ #include "ruby.h"
2
+
3
+ #define node_size(x) (((x)==NULL) ? 0 : ((x)->size))
4
+
5
+ /* Using http://www.link.cs.cmu.edu/link/ftp-site/splaying/top-down-size-splay.c as reference,
6
+ written by D. Sleator <sleator@cs.cmu.edu>, January 1994.
7
+ */
8
+
9
+ typedef struct struct_splaytree_node {
10
+ VALUE key;
11
+ VALUE value;
12
+ int size;
13
+ struct struct_splaytree_node *left;
14
+ struct struct_splaytree_node *right;
15
+ } splaytree_node;
16
+
17
+ typedef struct {
18
+ int (*compare_function)(VALUE key1, VALUE key2);
19
+ splaytree_node *root;
20
+ } splaytree;
21
+
22
+ typedef struct struct_ll_node {
23
+ splaytree_node *node;
24
+ struct struct_ll_node *next;
25
+ } ll_node;
26
+
27
+ static void recursively_free_nodes(splaytree_node *node) {
28
+ if(node) {
29
+ recursively_free_nodes(node->left);
30
+ recursively_free_nodes(node->right);
31
+ free(node);
32
+ }
33
+ return;
34
+ }
35
+
36
+ static splaytree* get_tree_from_self(VALUE self) {
37
+ splaytree *tree;
38
+ Data_Get_Struct(self, splaytree, tree);
39
+ return tree;
40
+ }
41
+
42
+ static splaytree_node* splay(splaytree *tree, splaytree_node *n, VALUE key) {
43
+ int cmp, cmp2, root_size, l_size, r_size;
44
+ splaytree_node N;
45
+ splaytree_node *l, *r, *y;
46
+
47
+ if (!n) return n;
48
+
49
+ N.left = N.right = NULL;
50
+ l = r = &N;
51
+ root_size = node_size(n);
52
+ l_size = r_size = 0;
53
+
54
+ while(1) {
55
+ cmp = tree->compare_function(key, n->key);
56
+ if (cmp == -1) {
57
+ if (!n->left) break;
58
+ cmp2 = tree->compare_function(key, n->left->key);
59
+ if (cmp2 == -1) {
60
+ y = n->left;
61
+ n->left = y->right;
62
+ y->right = n;
63
+ n->size = node_size(n->left) + node_size(n->right) + 1;
64
+ n = y;
65
+ if (!n->left) break;
66
+ }
67
+ r->left = n;
68
+ r = n;
69
+ n = n->left;
70
+ r_size += 1 + node_size(r->right);
71
+ } else if (cmp == 1) {
72
+ if (!n->right) break;
73
+ cmp2 = tree->compare_function(key, n->right->key);
74
+ if (cmp2 == 1) {
75
+ y = n->right;
76
+ n->right = y->left;
77
+ y->left = n;
78
+ n->size = node_size(n->left) + node_size(n->right) + 1;
79
+ n = y;
80
+ if (!n->right) break;
81
+ }
82
+ l->right = n;
83
+ l = n;
84
+ n = n->right;
85
+ l_size += 1 + node_size(l->left);
86
+ } else {
87
+ break;
88
+ }
89
+ }
90
+
91
+ l_size += node_size(n->left);
92
+ r_size += node_size(n->right);
93
+ n->size = l_size + r_size + 1;
94
+ l->right = r->left = NULL;
95
+
96
+ for (y = N.right; y != NULL; y = y->right) {
97
+ y->size = l_size;
98
+ l_size -= 1 + node_size(y->left);
99
+ }
100
+ for (y = N.left; y != NULL; y = y->left) {
101
+ y->size = r_size;
102
+ r_size -= 1 + node_size(y->right);
103
+ }
104
+
105
+ l->right = n->left;
106
+ r->left = n->right;
107
+ n->left = N.right;
108
+ n->right = N.left;
109
+
110
+ return n;
111
+ }
112
+
113
+ static int height(splaytree_node *h) {
114
+ int left_height, right_height;
115
+
116
+ if(!h) { return 0; }
117
+
118
+ left_height = 1 + height(h->left);
119
+ right_height = 1 + height(h->right);
120
+
121
+ return left_height > right_height ? left_height : right_height;
122
+ }
123
+
124
+ static splaytree* create_splaytree(int (*compare_function)(VALUE, VALUE)) {
125
+ splaytree *tree = ALLOC(splaytree);
126
+ tree->compare_function = compare_function;
127
+ tree->root = NULL;
128
+ return tree;
129
+ }
130
+
131
+ static splaytree_node* create_node(VALUE key, VALUE value) {
132
+ splaytree_node *new_node = ALLOC(splaytree_node);
133
+ new_node->key = key;
134
+ new_node->value = value;
135
+ new_node->left = NULL;
136
+ new_node->right = NULL;
137
+ return new_node;
138
+ }
139
+
140
+ static splaytree_node* insert(splaytree *tree, splaytree_node *n, VALUE key, VALUE value) {
141
+ int cmp;
142
+ splaytree_node *new_node;
143
+
144
+ if (n) {
145
+ n = splay(tree, n, key);
146
+ cmp = tree->compare_function(key, n->key);
147
+ if (cmp == 0) {
148
+ n->value = value;
149
+ return n;
150
+ }
151
+ }
152
+ new_node = create_node(key, value);
153
+ if (!n) {
154
+ new_node->left = new_node->right = NULL;
155
+ } else {
156
+ cmp = tree->compare_function(key, n->key);
157
+ if (cmp < 0) {
158
+ new_node->left = n->left;
159
+ new_node->right = n;
160
+ n->left = NULL;
161
+ n->size = 1 + node_size(n->right);
162
+ } else {
163
+ new_node->right = n->right;
164
+ new_node->left = n;
165
+ n->right = NULL;
166
+ n->size = 1 + node_size(n->left);
167
+ }
168
+ }
169
+ new_node->size = 1 + node_size(new_node->left) + node_size(new_node->right);
170
+ return new_node;
171
+ }
172
+
173
+ static VALUE get(splaytree *tree, VALUE key) {
174
+ int cmp;
175
+
176
+ if (!tree->root)
177
+ return Qnil;
178
+
179
+ tree->root = splay(tree, tree->root, key);
180
+ cmp = tree->compare_function(key, tree->root->key);
181
+ if (cmp == 0) {
182
+ return tree->root->value;
183
+ }
184
+ return Qnil;
185
+ }
186
+
187
+ static splaytree_node* delete(splaytree *tree, splaytree_node *n, VALUE key, VALUE *deleted) {
188
+ int cmp, tsize;
189
+ splaytree_node *x;
190
+
191
+ tsize = n->size;
192
+ n = splay(tree, n, key);
193
+ cmp = tree->compare_function(key, n->key);
194
+ if (cmp == 0) {
195
+ *deleted = n->value;
196
+ if (!n->left) {
197
+ x = n->right;
198
+ } else {
199
+ x = splay(tree, n->left, key);
200
+ x->right = n->right;
201
+ }
202
+ free(n);
203
+ if (x) {
204
+ x->size = tsize-1;
205
+ }
206
+ return x;
207
+ }
208
+ return n;
209
+ }
210
+
211
+ static splaytree* splaytree_each_node(splaytree *tree, splaytree_node *node, void (*each)(splaytree *tree_, splaytree_node *node_, void* args), void* arguments) {
212
+ if (!node)
213
+ return NULL;
214
+
215
+ if (node->left)
216
+ splaytree_each_node(tree, node->left, each, arguments);
217
+
218
+ (*each)(tree, node, arguments);
219
+
220
+ if (node->right)
221
+ splaytree_each_node(tree, node->right, each, arguments);
222
+ return tree;
223
+ }
224
+
225
+ static splaytree* splay_each(splaytree *tree, void (*each)(splaytree *tree, splaytree_node *node, void *args), void* arguments) {
226
+ if (tree->root)
227
+ splaytree_each_node(tree, tree->root, each, arguments);
228
+ return tree;
229
+ }
230
+
231
+ // Methods to be called in Ruby
232
+
233
+ static int id_compare_operator;
234
+
235
+ static int splaytree_compare_function(VALUE a, VALUE b) {
236
+ if (a == b) return 0;
237
+ if (FIXNUM_P(a) && FIXNUM_P(b)) {
238
+ long x = FIX2LONG(a), y = FIX2LONG(b);
239
+ if (x == y) return 0;
240
+ if (x > y) return 1;
241
+ return -1;
242
+ }
243
+ if (TYPE(a) == T_STRING && rb_obj_is_kind_of(a, rb_cString) &&
244
+ TYPE(b) == T_STRING && rb_obj_is_kind_of(b, rb_cString)) {
245
+ return rb_str_cmp(a, b);
246
+ }
247
+ return FIX2INT(rb_funcall((VALUE) a, id_compare_operator, 1, (VALUE) b));
248
+ }
249
+
250
+ static VALUE splaytree_init(VALUE self)
251
+ {
252
+ return self;
253
+ }
254
+
255
+ static void splaytree_mark(void *ptr) {
256
+ ll_node *current, *new, *last, *old;
257
+ if (ptr) {
258
+ splaytree *tree = ptr;
259
+
260
+ if (tree->root) {
261
+ current = ALLOC(ll_node);
262
+ last = current;
263
+ current->node = tree->root;
264
+ current->next = NULL;
265
+
266
+ while(current) {
267
+ rb_gc_mark(current->node->key);
268
+ rb_gc_mark(current->node->value);
269
+ if (current->node->left) {
270
+ new = ALLOC(ll_node);
271
+ new->node = current->node->left;
272
+ new->next = NULL;
273
+ last->next = new;
274
+ last = new;
275
+ }
276
+ if (current->node->right) {
277
+ new = ALLOC(ll_node);
278
+ new->node = current->node->right;
279
+ new->next = NULL;
280
+ last->next = new;
281
+ last = new;
282
+ }
283
+ old = current;
284
+ current = current->next;
285
+ free(old);
286
+ }
287
+ }
288
+ }
289
+ }
290
+
291
+ static void splaytree_free(void *ptr) {
292
+ if (ptr) {
293
+ splaytree *tree = ptr;
294
+ recursively_free_nodes(tree->root);
295
+ free(tree);
296
+ }
297
+ }
298
+
299
+ static VALUE splaytree_alloc(VALUE klass) {
300
+ splaytree *tree = create_splaytree(&splaytree_compare_function);
301
+ return Data_Wrap_Struct(klass, splaytree_mark, splaytree_free, tree);
302
+ }
303
+
304
+ static VALUE splaytree_push(VALUE self, VALUE key, VALUE value) {
305
+ splaytree *tree = get_tree_from_self(self);
306
+ tree->root = insert(tree, tree->root, key, value);
307
+ return value;
308
+ }
309
+
310
+ static VALUE splaytree_get(VALUE self, VALUE key) {
311
+ splaytree *tree = get_tree_from_self(self);
312
+ return get(tree, key);
313
+ }
314
+
315
+ static VALUE splaytree_size(VALUE self) {
316
+ splaytree *tree = get_tree_from_self(self);
317
+ if(!tree->root) { return INT2NUM(0); }
318
+ return INT2NUM(tree->root->size);
319
+ }
320
+
321
+ static VALUE splaytree_is_empty(VALUE self) {
322
+ splaytree *tree = get_tree_from_self(self);
323
+ return (tree->root ? Qfalse : Qtrue);
324
+ }
325
+
326
+ static VALUE splaytree_height(VALUE self) {
327
+ splaytree *tree = get_tree_from_self(self);
328
+ return INT2NUM(height(tree->root));
329
+ }
330
+
331
+ static VALUE splaytree_has_key(VALUE self, VALUE key) {
332
+ splaytree *tree = get_tree_from_self(self);
333
+ if(!tree->root) { return Qfalse; }
334
+ if(get(tree, key) == Qnil)
335
+ return Qfalse;
336
+
337
+ return Qtrue;
338
+ }
339
+
340
+ static VALUE splaytree_min_key(VALUE self) {
341
+ splaytree *tree = get_tree_from_self(self);
342
+ splaytree_node *node;
343
+
344
+ if(!tree->root)
345
+ return Qnil;
346
+
347
+ node = tree->root;
348
+ while (node->left)
349
+ node = node->left;
350
+
351
+ return node->key;
352
+ }
353
+
354
+ static VALUE splaytree_max_key(VALUE self) {
355
+ splaytree *tree = get_tree_from_self(self);
356
+ splaytree_node *node;
357
+
358
+ if(!tree->root)
359
+ return Qnil;
360
+
361
+ node = tree->root;
362
+ while (node->right)
363
+ node = node->right;
364
+
365
+ return node->key;
366
+ }
367
+
368
+ static VALUE splaytree_delete(VALUE self, VALUE key) {
369
+ VALUE deleted = Qnil;
370
+ splaytree *tree = get_tree_from_self(self);
371
+ if(!tree->root)
372
+ return Qnil;
373
+
374
+ tree->root = delete(tree, tree->root, key, &deleted);
375
+ return deleted;
376
+ }
377
+
378
+ static VALUE splaytree_clear(VALUE self) {
379
+ splaytree *tree = get_tree_from_self(self);
380
+ recursively_free_nodes(tree->root);
381
+ tree->root = NULL;
382
+ return Qnil;
383
+ }
384
+
385
+ static void splaytree_each_helper(splaytree *tree, splaytree_node *node, void *args) {
386
+ rb_yield(rb_ary_new3(2, node->key, node->value));
387
+ };
388
+
389
+ static VALUE splaytree_each(VALUE self) {
390
+ splaytree *tree = get_tree_from_self(self);
391
+ splay_each(tree, &splaytree_each_helper, NULL);
392
+ return self;
393
+ }
394
+
395
+ static VALUE CSplayTree;
396
+ static VALUE mContainers;
397
+ static VALUE namespace;
398
+
399
+ void Init_CSplayTreeMap() {
400
+ id_compare_operator = rb_intern("<=>");
401
+
402
+ namespace = rb_define_module("Algorithms");
403
+ mContainers = rb_define_module_under(namespace,"Containers");
404
+ CSplayTree = rb_define_class_under(mContainers, "CSplayTreeMap", rb_cObject);
405
+ rb_define_alloc_func(CSplayTree, splaytree_alloc);
406
+ rb_define_method(CSplayTree, "initialize", splaytree_init, 0);
407
+ rb_define_method(CSplayTree, "push", splaytree_push, 2);
408
+ rb_define_method(CSplayTree, "clear", splaytree_clear, 0);
409
+ rb_define_alias(CSplayTree, "[]=", "push");
410
+ rb_define_method(CSplayTree, "size", splaytree_size, 0);
411
+ rb_define_method(CSplayTree, "empty?", splaytree_is_empty, 0);
412
+ rb_define_method(CSplayTree, "height", splaytree_height, 0);
413
+ rb_define_method(CSplayTree, "min_key", splaytree_min_key, 0);
414
+ rb_define_method(CSplayTree, "max_key", splaytree_max_key, 0);
415
+ rb_define_method(CSplayTree, "each", splaytree_each, 0);
416
+ rb_define_method(CSplayTree, "get", splaytree_get, 1);
417
+ rb_define_alias(CSplayTree, "[]", "get");
418
+ rb_define_method(CSplayTree, "has_key?", splaytree_has_key, 1);
419
+ rb_define_method(CSplayTree, "delete", splaytree_delete, 1);
420
+ rb_include_module(CSplayTree, rb_eval_string("Enumerable"));
421
+ }
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{grosser-algorithms}
5
+ s.version = "0.4.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Kanwei Li"]
9
+ s.date = %q{2010-08-10}
10
+ s.description = %q{A library of algorithms and containers.}
11
+ s.email = %q{kanwei@gmail.com}
12
+ s.extensions = ["ext/algorithms/string/extconf.rb", "ext/containers/deque/extconf.rb", "ext/containers/rbtree_map/extconf.rb", "ext/containers/splaytree_map/extconf.rb"]
13
+ s.extra_rdoc_files = ["README.markdown", "ext/algorithms/string/extconf.rb", "ext/algorithms/string/string.c", "ext/containers/deque/deque.c", "ext/containers/deque/extconf.rb", "ext/containers/rbtree_map/extconf.rb", "ext/containers/rbtree_map/rbtree.c", "ext/containers/splaytree_map/extconf.rb", "ext/containers/splaytree_map/splaytree.c", "lib/algorithms.rb", "lib/algorithms/search.rb", "lib/algorithms/sort.rb", "lib/algorithms/string.rb", "lib/containers/deque.rb", "lib/containers/heap.rb", "lib/containers/kd_tree.rb", "lib/containers/priority_queue.rb", "lib/containers/queue.rb", "lib/containers/rb_tree_map.rb", "lib/containers/splay_tree_map.rb", "lib/containers/stack.rb", "lib/containers/suffix_array.rb", "lib/containers/trie.rb"]
14
+ s.files = ["History.txt", "Manifest", "README.markdown", "Rakefile", "algorithms.gemspec", "benchmarks/deque.rb", "benchmarks/sorts.rb", "benchmarks/treemaps.rb", "ext/algorithms/string/extconf.rb", "ext/algorithms/string/string.c", "ext/containers/deque/deque.c", "ext/containers/deque/extconf.rb", "ext/containers/rbtree_map/extconf.rb", "ext/containers/rbtree_map/rbtree.c", "ext/containers/splaytree_map/extconf.rb", "ext/containers/splaytree_map/splaytree.c", "lib/algorithms.rb", "lib/algorithms/search.rb", "lib/algorithms/sort.rb", "lib/algorithms/string.rb", "lib/containers/deque.rb", "lib/containers/heap.rb", "lib/containers/kd_tree.rb", "lib/containers/priority_queue.rb", "lib/containers/queue.rb", "lib/containers/rb_tree_map.rb", "lib/containers/splay_tree_map.rb", "lib/containers/stack.rb", "lib/containers/suffix_array.rb", "lib/containers/trie.rb", "spec/deque_gc_mark_spec.rb", "spec/deque_spec.rb", "spec/heap_spec.rb", "spec/kd_expected_out.txt", "spec/kd_test_in.txt", "spec/kd_tree_spec.rb", "spec/map_gc_mark_spec.rb", "spec/priority_queue_spec.rb", "spec/queue_spec.rb", "spec/rb_tree_map_spec.rb", "spec/search_spec.rb", "spec/sort_spec.rb", "spec/splay_tree_map_spec.rb", "spec/stack_spec.rb", "spec/string_spec.rb", "spec/suffix_array_spec.rb", "spec/trie_spec.rb", "grosser-algorithms.gemspec"]
15
+ s.homepage = %q{http://rubyforge.org/projects/algorithms/}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Grosser-algorithms", "--main", "README.markdown"]
17
+ s.require_paths = ["lib", "ext"]
18
+ s.rubyforge_project = %q{grosser-algorithms}
19
+ s.rubygems_version = %q{1.3.6}
20
+ s.summary = %q{A library of algorithms and containers.}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ else
28
+ end
29
+ else
30
+ end
31
+ end