victory 0.0.0 → 0.0.1

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rubocop.yml +11 -1
  4. data/README.md +4 -6
  5. data/Rakefile +11 -4
  6. data/USAGE.md +159 -0
  7. data/ext/algorithms/string/LICENSE.md +21 -0
  8. data/ext/algorithms/string/extconf.rb +4 -0
  9. data/ext/algorithms/string/string.c +68 -0
  10. data/ext/containers/bst/LICENSE.md +21 -0
  11. data/ext/containers/bst/bst.c +247 -0
  12. data/ext/containers/bst/extconf.rb +4 -0
  13. data/ext/containers/deque/LICENSE.md +21 -0
  14. data/ext/containers/deque/deque.c +247 -0
  15. data/ext/containers/deque/extconf.rb +4 -0
  16. data/ext/containers/rbtree_map/LICENSE.md +21 -0
  17. data/ext/containers/rbtree_map/extconf.rb +4 -0
  18. data/ext/containers/rbtree_map/rbtree.c +498 -0
  19. data/ext/containers/splaytree_map/LICENSE.md +21 -0
  20. data/ext/containers/splaytree_map/extconf.rb +4 -0
  21. data/ext/containers/splaytree_map/splaytree.c +419 -0
  22. data/ext/containers/xor_list/extconf.rb +4 -0
  23. data/ext/containers/xor_list/xor_list.c +122 -0
  24. data/lib/algorithms/search.rb +104 -0
  25. data/lib/algorithms/sort.rb +389 -0
  26. data/lib/algorithms/string.rb +29 -0
  27. data/lib/containers/deque.rb +193 -0
  28. data/lib/containers/heap.rb +524 -0
  29. data/lib/containers/kd_tree.rb +131 -0
  30. data/lib/containers/list.rb +81 -0
  31. data/lib/containers/prefix_tree.rb +61 -0
  32. data/lib/containers/priority_queue.rb +135 -0
  33. data/lib/containers/queue.rb +89 -0
  34. data/lib/containers/rb_tree_map.rb +420 -0
  35. data/lib/containers/splay_tree_map.rb +290 -0
  36. data/lib/containers/stack.rb +88 -0
  37. data/lib/containers/suffix_array.rb +92 -0
  38. data/lib/containers/trie.rb +204 -0
  39. data/lib/containers/tuple.rb +20 -0
  40. data/lib/victory/version.rb +1 -1
  41. data/lib/victory.rb +8 -1
  42. data/victory.gemspec +12 -3
  43. metadata +73 -12
  44. data/.idea/encodings.xml +0 -4
  45. data/.idea/misc.xml +0 -7
  46. data/.idea/modules.xml +0 -8
  47. data/.idea/victory.iml +0 -13
  48. data/.idea/workspace.xml +0 -233
  49. data/ext/victory/extconf.rb +0 -3
  50. data/ext/victory/victory.c +0 -9
  51. data/ext/victory/victory.h +0 -6
@@ -0,0 +1,498 @@
1
+ #include "ruby.h"
2
+
3
+ #define RED 1
4
+ #define BLACK 0
5
+
6
+ #define FALSE 0
7
+ #define TRUE 1
8
+
9
+ typedef struct struct_rbtree_node {
10
+ int color;
11
+ VALUE key;
12
+ VALUE value;
13
+ struct struct_rbtree_node *left;
14
+ struct struct_rbtree_node *right;
15
+ unsigned int height;
16
+ unsigned int num_nodes;
17
+ } rbtree_node;
18
+
19
+ typedef struct {
20
+ unsigned int black_height;
21
+ int (*compare_function)(VALUE key1, VALUE key2);
22
+ rbtree_node *root;
23
+ } rbtree;
24
+
25
+ typedef struct struct_ll_node {
26
+ rbtree_node *node;
27
+ struct struct_ll_node *next;
28
+ } ll_node;
29
+
30
+ static void recursively_free_nodes(rbtree_node *node) {
31
+ if(node) {
32
+ recursively_free_nodes(node->left);
33
+ recursively_free_nodes(node->right);
34
+ xfree(node);
35
+ }
36
+ return;
37
+ }
38
+
39
+ static rbtree* get_tree_from_self(VALUE self) {
40
+ rbtree *tree;
41
+ Data_Get_Struct(self, rbtree, tree);
42
+ return tree;
43
+ }
44
+
45
+ static int isred(rbtree_node *node) {
46
+ if(!node) { return FALSE; }
47
+
48
+ if(node->color == RED) { return TRUE; }
49
+ else return FALSE;
50
+ }
51
+
52
+ static void colorflip(rbtree_node *node) {
53
+ node->color = !node->color;
54
+ node->left->color = !node->left->color;
55
+ node->right->color = !node->right->color;
56
+ }
57
+
58
+ static int size(rbtree_node *h) {
59
+ if(!h) {
60
+ return 0;
61
+ }
62
+ else return h->num_nodes;
63
+ }
64
+
65
+ static int height(rbtree_node *h) {
66
+ if(!h) { return 0; }
67
+ else return h->height;
68
+ }
69
+
70
+ static rbtree_node* set_num_nodes(rbtree_node *h) {
71
+ h->num_nodes = size(h->left) + size(h->right) + 1;
72
+ if ( height(h->left) > height(h->right) ) {
73
+ h->height = height(h->left) +1;
74
+ }
75
+ else {
76
+ h->height = height(h->right) +1;
77
+ }
78
+ return h;
79
+ }
80
+
81
+ static rbtree_node* rotate_left(rbtree_node *h) {
82
+ rbtree_node *x = h->right;
83
+ h->right = x->left;
84
+ x->left = set_num_nodes(h);
85
+ x->color = x->left->color;
86
+ x->left->color = RED;
87
+ return set_num_nodes(x);
88
+ }
89
+
90
+ static rbtree_node* rotate_right(rbtree_node *h) {
91
+ rbtree_node *x = h->left;
92
+ h->left = x->right;
93
+ x->right = set_num_nodes(h);
94
+ x->color = x->right->color;
95
+ x->right->color = RED;
96
+ return set_num_nodes(x);
97
+ }
98
+
99
+ static rbtree_node* move_red_left(rbtree_node *h) {
100
+ colorflip(h);
101
+ if ( isred(h->right->left) ) {
102
+ h->right = rotate_right(h->right);
103
+ h = rotate_left(h);
104
+ colorflip(h);
105
+ }
106
+ return h;
107
+ }
108
+
109
+ static rbtree_node* move_red_right(rbtree_node *h) {
110
+ colorflip(h);
111
+ if ( isred(h->left->left) ) {
112
+ h = rotate_right(h);
113
+ colorflip(h);
114
+ }
115
+ return h;
116
+ }
117
+
118
+ static rbtree_node* fixup(rbtree_node *h) {
119
+ if ( isred(h->right) )
120
+ h = rotate_left(h);
121
+
122
+ if ( isred(h->left) && isred(h->left->left) )
123
+ h = rotate_right(h);
124
+
125
+ if ( isred(h->left) && isred(h->right) )
126
+ colorflip(h);
127
+
128
+ return set_num_nodes(h);
129
+ }
130
+
131
+ static rbtree* create_rbtree(int (*compare_function)(VALUE, VALUE)) {
132
+ rbtree *tree = ALLOC(rbtree);
133
+ tree->black_height = 0;
134
+ tree->compare_function = compare_function;
135
+ tree->root = NULL;
136
+ return tree;
137
+ }
138
+
139
+ static rbtree_node* insert(rbtree *tree, rbtree_node *node, VALUE key, VALUE value) {
140
+ int cmp;
141
+
142
+ // This slot is empty, so we insert our new node
143
+ if(!node) {
144
+ rbtree_node *new_node = ALLOC(rbtree_node);
145
+ new_node->key = key;
146
+ new_node->value = value;
147
+ new_node->color = RED;
148
+ new_node->height = 1;
149
+ new_node->num_nodes = 1;
150
+ new_node->left = NULL;
151
+ new_node->right = NULL;
152
+ return new_node;
153
+ }
154
+
155
+ // Insert left or right, recursively
156
+ cmp = tree->compare_function(key, node->key);
157
+ if (cmp == 0) { node->value = value; }
158
+ else if (cmp == -1) { node->left = insert(tree, node->left, key, value); }
159
+ else { node->right = insert(tree, node->right, key, value); }
160
+
161
+ // Fix our tree to keep left-lean
162
+ if (isred(node->right)) { node = rotate_left(node); }
163
+ if (isred(node->left) && isred(node->left->left)) { node = rotate_right(node); }
164
+ if ( isred(node->left) && isred(node->right) ) {
165
+ colorflip(node);
166
+ }
167
+ return set_num_nodes(node);
168
+ }
169
+
170
+ static VALUE get(rbtree *tree, rbtree_node *node, VALUE key) {
171
+ int cmp;
172
+ if (!node) {
173
+ return Qnil;
174
+ }
175
+
176
+ cmp = tree->compare_function(key, node->key);
177
+ if (cmp == 0) { return node->value; }
178
+ else if (cmp == -1) { return get(tree, node->left, key); }
179
+ else { return get(tree, node->right, key); }
180
+
181
+ }
182
+
183
+ static VALUE min_key(rbtree_node *node) {
184
+ while (node->left)
185
+ node = node->left;
186
+
187
+ return node->key;
188
+ }
189
+
190
+ static VALUE max_key(rbtree_node *node) {
191
+ while (node->right)
192
+ node = node->right;
193
+
194
+ return node->key;
195
+ }
196
+
197
+ static rbtree_node* delete_min(rbtree_node *h, VALUE *deleted_value) {
198
+ if ( !h->left ) {
199
+ if(deleted_value)
200
+ *deleted_value = h->value;
201
+ xfree(h);
202
+ return NULL;
203
+ }
204
+
205
+ if ( !isred(h->left) && !isred(h->left->left) )
206
+ h = move_red_left(h);
207
+
208
+ h->left = delete_min(h->left, deleted_value);
209
+
210
+ return fixup(h);
211
+ }
212
+
213
+ static rbtree_node* delete_max(rbtree_node *h, VALUE *deleted_value) {
214
+ if ( isred(h->left) )
215
+ h = rotate_right(h);
216
+
217
+ if ( !h->right ) {
218
+ *deleted_value = h->value;
219
+ xfree(h);
220
+ return NULL;
221
+ }
222
+
223
+ if ( !isred(h->right) && !isred(h->right->left) )
224
+ h = move_red_right(h);
225
+
226
+ h->right = delete_max(h->right, deleted_value);
227
+
228
+ return fixup(h);
229
+ }
230
+
231
+ static rbtree_node* delete(rbtree *tree, rbtree_node *node, VALUE key, VALUE *deleted_value) {
232
+ int cmp;
233
+ VALUE minimum_key;
234
+ cmp = tree->compare_function(key, node->key);
235
+ if (cmp == -1) {
236
+ if ( !isred(node->left) && !isred(node->left->left) )
237
+ node = move_red_left(node);
238
+
239
+ node->left = delete(tree, node->left, key, deleted_value);
240
+ }
241
+ else {
242
+ if ( isred(node->left) )
243
+ node = rotate_right(node);
244
+
245
+ cmp = tree->compare_function(key, node->key);
246
+ if ( (cmp == 0) && !node->right ) {
247
+ *deleted_value = node->value;
248
+ xfree(node);
249
+ return NULL;
250
+ }
251
+
252
+ if ( !isred(node->right) && !isred(node->right->left) )
253
+ node = move_red_right(node);
254
+
255
+ cmp = tree->compare_function(key, node->key);
256
+ if (cmp == 0) {
257
+ *deleted_value = node->value;
258
+ minimum_key = min_key(node->right);
259
+ node->value = get(tree, node->right, minimum_key);
260
+ node->key = minimum_key;
261
+ node->right = delete_min(node->right, NULL);
262
+ }
263
+ else {
264
+ node->right = delete(tree, node->right, key, deleted_value);
265
+ }
266
+ }
267
+ return fixup(node);
268
+ }
269
+
270
+ static rbtree* rbtree_each_node(rbtree *tree, rbtree_node *node, void (*each)(rbtree *tree_, rbtree_node *node_, void* args), void* arguments) {
271
+ if (!node)
272
+ return NULL;
273
+
274
+ if (node->left)
275
+ rbtree_each_node(tree, node->left, each, arguments);
276
+ (*each)(tree, node, arguments);
277
+ if (node->right)
278
+ rbtree_each_node(tree, node->right, each, arguments);
279
+ return tree;
280
+ }
281
+
282
+ static rbtree* rbt_each(rbtree *tree, void (*each)(rbtree *tree, rbtree_node *node, void *args), void* arguments) {
283
+ if (tree->root)
284
+ rbtree_each_node(tree, tree->root, each, arguments);
285
+ return tree;
286
+ }
287
+
288
+ // Methods to be called in Ruby
289
+
290
+ static VALUE id_compare_operator;
291
+
292
+ static int rbtree_compare_function(VALUE a, VALUE b) {
293
+ if (a == b) return 0;
294
+ if (FIXNUM_P(a) && FIXNUM_P(b)) {
295
+ long x = FIX2LONG(a), y = FIX2LONG(b);
296
+ if (x == y) return 0;
297
+ if (x > y) return 1;
298
+ return -1;
299
+ }
300
+ if (TYPE(a) == T_STRING && rb_obj_is_kind_of(a, rb_cString) &&
301
+ TYPE(b) == T_STRING && rb_obj_is_kind_of(b, rb_cString)) {
302
+ return rb_str_cmp(a, b);
303
+ }
304
+ return FIX2INT(rb_funcall((VALUE) a, id_compare_operator, 1, (VALUE) b));
305
+ }
306
+
307
+ static VALUE rbtree_init(VALUE self)
308
+ {
309
+ return self;
310
+ }
311
+
312
+ static void rbtree_mark(void *ptr) {
313
+ ll_node *current, *new, *last, *old;
314
+ if (ptr) {
315
+ rbtree *tree = ptr;
316
+
317
+ if (tree->root) {
318
+ current = ALLOC(ll_node);
319
+ last = current;
320
+ current->node = tree->root;
321
+ current->next = NULL;
322
+
323
+ while(current) {
324
+ rb_gc_mark(current->node->key);
325
+ rb_gc_mark(current->node->value);
326
+ if (current->node->left) {
327
+ new = ALLOC(ll_node);
328
+ new->node = current->node->left;
329
+ new->next = NULL;
330
+ last->next = new;
331
+ last = new;
332
+ }
333
+ if (current->node->right) {
334
+ new = ALLOC(ll_node);
335
+ new->node = current->node->right;
336
+ new->next = NULL;
337
+ last->next = new;
338
+ last = new;
339
+ }
340
+ old = current;
341
+ current = current->next;
342
+ xfree(old);
343
+ }
344
+ }
345
+ }
346
+ }
347
+
348
+ static void rbtree_free(void *ptr) {
349
+ if (ptr) {
350
+ rbtree *tree = ptr;
351
+ recursively_free_nodes(tree->root);
352
+ xfree(tree);
353
+ }
354
+ }
355
+
356
+ static VALUE rbtree_alloc(VALUE klass) {
357
+ rbtree *tree = create_rbtree(&rbtree_compare_function);
358
+ return Data_Wrap_Struct(klass, rbtree_mark, rbtree_free, tree);
359
+ }
360
+
361
+ static VALUE rbtree_push(VALUE self, VALUE key, VALUE value) {
362
+ rbtree *tree = get_tree_from_self(self);
363
+ tree->root = insert(tree, tree->root, key, value);
364
+ return value;
365
+ }
366
+
367
+ static VALUE rbtree_get(VALUE self, VALUE key) {
368
+ rbtree *tree = get_tree_from_self(self);
369
+ return get(tree, tree->root, key);
370
+ }
371
+
372
+ static VALUE rbtree_size(VALUE self) {
373
+ rbtree *tree = get_tree_from_self(self);
374
+ return INT2NUM(size(tree->root));
375
+ }
376
+
377
+ static VALUE rbtree_is_empty(VALUE self) {
378
+ rbtree *tree = get_tree_from_self(self);
379
+ return (tree->root ? Qfalse : Qtrue);
380
+ }
381
+
382
+ static VALUE rbtree_height(VALUE self) {
383
+ rbtree *tree = get_tree_from_self(self);
384
+ return INT2NUM(height(tree->root));
385
+ }
386
+
387
+ static VALUE rbtree_has_key(VALUE self, VALUE key) {
388
+ rbtree *tree = get_tree_from_self(self);
389
+ if(!tree->root) { return Qfalse; }
390
+ if(get(tree, tree->root, key) == Qnil)
391
+ return Qfalse;
392
+
393
+ return Qtrue;
394
+ }
395
+
396
+ static VALUE rbtree_min_key(VALUE self) {
397
+ rbtree *tree = get_tree_from_self(self);
398
+ if(!tree->root)
399
+ return Qnil;
400
+
401
+ return min_key(tree->root);
402
+ }
403
+
404
+ static VALUE rbtree_max_key(VALUE self) {
405
+ rbtree *tree = get_tree_from_self(self);
406
+ if(!tree->root)
407
+ return Qnil;
408
+
409
+ return max_key(tree->root);
410
+ }
411
+
412
+ static VALUE rbtree_delete(VALUE self, VALUE key) {
413
+ VALUE deleted_value;
414
+ rbtree *tree = get_tree_from_self(self);
415
+ if(!tree->root)
416
+ return Qnil;
417
+
418
+ tree->root = delete(tree, tree->root, key, &deleted_value);
419
+ if(tree->root)
420
+ tree->root->color = BLACK;
421
+
422
+ if(deleted_value) {
423
+ return deleted_value;
424
+ }
425
+
426
+ return Qnil;
427
+ }
428
+
429
+ static VALUE rbtree_delete_min(VALUE self) {
430
+ VALUE deleted_value;
431
+ rbtree *tree = get_tree_from_self(self);
432
+ if(!tree->root)
433
+ return Qnil;
434
+
435
+ tree->root = delete_min(tree->root, &deleted_value);
436
+ if(tree->root)
437
+ tree->root->color = BLACK;
438
+
439
+ if(deleted_value) {
440
+ return deleted_value;
441
+ }
442
+
443
+ return Qnil;
444
+ }
445
+
446
+ static VALUE rbtree_delete_max(VALUE self) {
447
+ VALUE deleted_value;
448
+ rbtree *tree = get_tree_from_self(self);
449
+ if(!tree->root)
450
+ return Qnil;
451
+
452
+ tree->root = delete_max(tree->root, &deleted_value);
453
+ if(tree->root)
454
+ tree->root->color = BLACK;
455
+
456
+ if(deleted_value) {
457
+ return deleted_value;
458
+ }
459
+
460
+ return Qnil;
461
+ }
462
+
463
+ static void rbtree_each_helper(rbtree *tree, rbtree_node *node, void *args) {
464
+ rb_yield(rb_ary_new3(2, node->key, node->value));
465
+ };
466
+
467
+ static VALUE rbtree_each(VALUE self) {
468
+ rbtree *tree = get_tree_from_self(self);
469
+ rbt_each(tree, &rbtree_each_helper, NULL);
470
+ return self;
471
+ }
472
+
473
+ static VALUE cRBTree;
474
+ static VALUE mContainers;
475
+
476
+ void Init_CRBTreeMap() {
477
+ id_compare_operator = rb_intern("<=>");
478
+
479
+ mContainers = rb_define_module("Containers");
480
+ cRBTree = rb_define_class_under(mContainers, "CRBTreeMap", rb_cObject);
481
+ rb_define_alloc_func(cRBTree, rbtree_alloc);
482
+ rb_define_method(cRBTree, "initialize", rbtree_init, 0);
483
+ rb_define_method(cRBTree, "push", rbtree_push, 2);
484
+ rb_define_alias(cRBTree, "[]=", "push");
485
+ rb_define_method(cRBTree, "size", rbtree_size, 0);
486
+ rb_define_method(cRBTree, "empty?", rbtree_is_empty, 0);
487
+ rb_define_method(cRBTree, "height", rbtree_height, 0);
488
+ rb_define_method(cRBTree, "min_key", rbtree_min_key, 0);
489
+ rb_define_method(cRBTree, "max_key", rbtree_max_key, 0);
490
+ rb_define_method(cRBTree, "delete_min", rbtree_delete_min, 0);
491
+ rb_define_method(cRBTree, "delete_max", rbtree_delete_max, 0);
492
+ rb_define_method(cRBTree, "each", rbtree_each, 0);
493
+ rb_define_method(cRBTree, "get", rbtree_get, 1);
494
+ rb_define_alias(cRBTree, "[]", "get");
495
+ rb_define_method(cRBTree, "has_key?", rbtree_has_key, 1);
496
+ rb_define_method(cRBTree, "delete", rbtree_delete, 1);
497
+ rb_include_module(cRBTree, rb_eval_string("Enumerable"));
498
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2009 Kanwei Li
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ extension_name = "CSplayTreeMap"
3
+ dir_config(extension_name)
4
+ create_makefile(extension_name)