stakach-algorithms 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,97 @@
1
+ # algorithms
2
+
3
+ * Official homes are here on github, and at [rubyforge](http://rubyforge.org/projects/algorithms/)
4
+ * Documentation: [http://algorithms.rubyforge.org/](http://algorithms.rubyforge.org/)
5
+
6
+ ## DESCRIPTION:
7
+
8
+ Started as a [Google Summer of Code 2008](http://code.google.com/soc/2008/ruby/about.html) project
9
+
10
+ Written by [Kanwei Li](http://kanwei.com/), mentored by Austin Ziegler
11
+
12
+ Original Proposal: Using the right data structure or algorithm for the situation is an important
13
+ aspect of programming. In computer science literature, many data structures
14
+ and algorithms have been researched and extensively documented. However, there
15
+ is still no standard library in Ruby implementing useful structures and
16
+ algorithms like Red/Black Trees, tries, different sorting algorithms, etc.
17
+ This project will create such a library with documentation on when to use a
18
+ particular structure/algorithm. It will also come with a benchmark suite to
19
+ compare performance in different situations.
20
+
21
+ ## FEATURES:
22
+
23
+ Done so far:
24
+
25
+ * Heaps Algorithms::Containers::Heap, Containers::MaxHeap, Containers::MinHeap
26
+ * Priority Queue Algorithms::Containers::PriorityQueue
27
+ * Deque Algorithms::Containers::Deque, Containers::CDeque (C extension), Containers::RubyDeque
28
+ * Stack Algorithms::Containers::Stack (uses Deque)
29
+ * Queue Algorithms::Containers::Queue (uses Deque)
30
+ * Red-Black Trees Algorithms::Containers::RBTreeMap, Containers::CRBTreeMap (C extension), Containers::RubyRBTreeMap
31
+ * Splay Trees Algorithms::Containers::SplayTreeMap, Containers::CSplayTreeMap (C extension), Containers::RubySplayTreeMap
32
+ * Tries Algorithms::Containers::Trie
33
+ * Suffix Array Algorithms::Containers::SuffixArray
34
+ * kd Tree Algorithms::Containers::KDTree
35
+
36
+ * Search algorithms
37
+ - Binary Search Algorithms::Algorithms::Search.binary_search
38
+ - Knuth-Morris-Pratt Algorithms::Algorithms::Search.kmp_search
39
+ * Sort algorithms
40
+ - Bubble sort Algorithms::Algorithms::Sort.bubble_sort
41
+ - Comb sort Algorithms::Algorithms::Sort.comb_sort
42
+ - Selection sort Algorithms::Algorithms::Sort.selection_sort
43
+ - Heapsort Algorithms::Algorithms::Sort.heapsort
44
+ - Insertion sort Algorithms::Algorithms::Sort.insertion_sort
45
+ - Shell sort Algorithms::Algorithms::Sort.shell_sort
46
+ - Quicksort Algorithms::Algorithms::Sort.quicksort
47
+ - Mergesort Algorithms::Algorithms::Sort.mergesort
48
+
49
+ ## SYNOPSIS:
50
+
51
+ require 'rubygems'
52
+ require 'algorithms'
53
+ max_heap = Algorithms::Containers::MaxHeap.new
54
+
55
+ # To not have to type "Algorithms::" before each class, use:
56
+ include Algorithms
57
+
58
+ max_heap = Containers::MaxHeap.new
59
+
60
+ # To not have to type "Containers::" before each class, use:
61
+ include Containers
62
+ max_heap = MaxHeap.new
63
+
64
+
65
+ ## REQUIREMENTS:
66
+
67
+ * Ruby 1.8 compatible Ruby, or Ruby 1.9
68
+ * C compiler for C extensions (optional, but very much recommended for vast performance benefits)
69
+
70
+ ## INSTALL:
71
+
72
+ * sudo gem install algorithms
73
+
74
+ ## LICENSE:
75
+
76
+ (The MIT License)
77
+
78
+ Algorithms and Containers project is Copyright (c) 2009 Kanwei Li
79
+
80
+ Permission is hereby granted, free of charge, to any person obtaining
81
+ a copy of this software and associated documentation files (the
82
+ 'Software'), to deal in the Software without restriction, including
83
+ without limitation the rights to use, copy, modify, merge, publish,
84
+ distribute, sublicense, and/or sell copies of the Software, and to
85
+ permit persons to whom the Software is furnished to do so, subject to
86
+ the following conditions:
87
+
88
+ The above copyright notice and this permission notice shall be
89
+ included in all copies or substantial portions of the Software.
90
+
91
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
92
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
93
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
94
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
95
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
96
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
97
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ require 'echoe'
2
+ require "rake/clean"
3
+ OBJ = FileList['**/*.rbc']
4
+ CLEAN.include(OBJ)
5
+
6
+ Echoe.new('algorithms') do |p|
7
+ p.author = 'Kanwei Li'
8
+ p.email = 'kanwei@gmail.com'
9
+ p.summary = 'A library of algorithms and containers.'
10
+ p.url = 'http://rubyforge.org/projects/algorithms/'
11
+ p.version = "0.2.0"
12
+ p.runtime_dependencies = []
13
+ end
14
+
15
+ task :push do
16
+ sh "git push" # Rubyforge
17
+ sh "git push --tags" # Rubyforge
18
+ sh "git push gh" # Github
19
+ sh "git push gh --tags" # Github
20
+ end
21
+
22
+ task :hanna do
23
+ sh "rm -fr doc"
24
+ sh "hanna -SN lib/ -m Algorithms"
25
+ sh "scp -rq doc/* kanwei@rubyforge.org:/var/www/gforge-projects/algorithms"
26
+ end
27
+
@@ -0,0 +1,249 @@
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_mark(void *ptr) {
60
+ if (ptr) {
61
+ deque *deque = ptr;
62
+ deque_node *node = deque->front;
63
+ while(node) {
64
+ rb_gc_mark(node->obj);
65
+ node = node->right;
66
+ }
67
+ }
68
+ }
69
+
70
+ static void deque_free(void *ptr) {
71
+ if (ptr) {
72
+ deque *deque = ptr;
73
+ free_nodes(deque->front);
74
+ free(deque);
75
+ }
76
+ }
77
+
78
+ static VALUE deque_alloc(VALUE klass) {
79
+ deque *deque = create_deque();
80
+ return Data_Wrap_Struct(klass, deque_mark, deque_free, deque);
81
+ }
82
+
83
+ static VALUE deque_push_front(VALUE self, VALUE obj) {
84
+ deque *deque = get_deque_from_self(self);
85
+ deque_node *node = create_node(obj);
86
+ if(deque->front) {
87
+ node->right = deque->front;
88
+ deque->front->left = node;
89
+ deque->front = node;
90
+ }
91
+ else {
92
+ deque->front = node;
93
+ deque->back = node;
94
+ }
95
+ deque->size++;
96
+ return obj;
97
+ }
98
+
99
+ static VALUE deque_push_back(VALUE self, VALUE obj) {
100
+ deque *deque = get_deque_from_self(self);
101
+ deque_node *node = create_node(obj);
102
+ if(deque->back) {
103
+ node->left = deque->back;
104
+ deque->back->right = node;
105
+ deque->back = node;
106
+ }
107
+ else {
108
+ deque->front = node;
109
+ deque->back = node;
110
+ }
111
+ deque->size++;
112
+ return obj;
113
+ }
114
+
115
+ static VALUE deque_pop_front(VALUE self) {
116
+ deque *deque = get_deque_from_self(self);
117
+ VALUE obj;
118
+ if(!deque->front)
119
+ return Qnil;
120
+ deque_node *node = deque->front;
121
+ obj = node->obj;
122
+ if(deque->size == 1) {
123
+ clear_deque(deque);
124
+ return obj;
125
+ }
126
+ deque->front->right->left = NULL;
127
+ deque->front = deque->front->right;
128
+ deque->size--;
129
+ return obj;
130
+ }
131
+
132
+ static VALUE deque_front(VALUE self) {
133
+ deque *deque = get_deque_from_self(self);
134
+ if(deque->front)
135
+ return deque->front->obj;
136
+
137
+ return Qnil;
138
+ }
139
+
140
+ static VALUE deque_back(VALUE self) {
141
+ deque *deque = get_deque_from_self(self);
142
+ if(deque->back)
143
+ return deque->back->obj;
144
+
145
+ return Qnil;
146
+ }
147
+
148
+ static VALUE deque_pop_back(VALUE self) {
149
+ deque *deque = get_deque_from_self(self);
150
+ VALUE obj;
151
+ if(!deque->back)
152
+ return Qnil;
153
+ deque_node *node = deque->back;
154
+ obj = node->obj;
155
+ if(deque->size == 1) {
156
+ clear_deque(deque);
157
+ return obj;
158
+ }
159
+ deque->back->left->right = NULL;
160
+ deque->back = deque->back->left;
161
+ deque->size--;
162
+ return obj;
163
+ }
164
+
165
+ static VALUE deque_clear(VALUE self) {
166
+ deque *deque = get_deque_from_self(self);
167
+ clear_deque(deque);
168
+ return Qnil;
169
+ }
170
+
171
+ static VALUE deque_size(VALUE self) {
172
+ deque *deque = get_deque_from_self(self);
173
+ return INT2NUM(deque->size);
174
+ }
175
+
176
+ static VALUE deque_is_empty(VALUE self) {
177
+ deque *deque = get_deque_from_self(self);
178
+ return (deque->size == 0) ? Qtrue : Qfalse;
179
+ }
180
+
181
+ static VALUE deque_each_forward(VALUE self) {
182
+ deque *deque = get_deque_from_self(self);
183
+ deque_node *node = deque->front;
184
+ while(node) {
185
+ rb_yield(node->obj);
186
+ node = node->right;
187
+ }
188
+ return self;
189
+ }
190
+
191
+ static VALUE deque_each_backward(VALUE self) {
192
+ deque *deque = get_deque_from_self(self);
193
+ deque_node *node = deque->back;
194
+ while(node) {
195
+ rb_yield(node->obj);
196
+ node = node->left;
197
+ }
198
+ return self;
199
+ }
200
+
201
+ static VALUE deque_init(int argc, VALUE *argv, VALUE self)
202
+ {
203
+ int len, i;
204
+ VALUE ary;
205
+
206
+ if(argc == 0) {
207
+ return self;
208
+ }
209
+ else if(argc > 1) {
210
+ rb_raise(rb_eArgError, "wrong number of arguments");
211
+ }
212
+ else {
213
+ ary = rb_check_array_type(argv[0]);
214
+ if(!NIL_P(ary)) {
215
+ len = RARRAY_LEN(ary);
216
+ for (i = 0; i < len; i++) {
217
+ deque_push_back(self, RARRAY_PTR(ary)[i]);
218
+ }
219
+ }
220
+ }
221
+ return self;
222
+ }
223
+
224
+ static VALUE cDeque;
225
+ static VALUE mContainers;
226
+ static VALUE namespace;
227
+
228
+ void Init_CDeque() {
229
+ namespace = rb_define_module("Algorithms");
230
+ mContainers = rb_define_module_under(namespace,"Containers");
231
+ cDeque = rb_define_class_under(mContainers, "CDeque", rb_cObject);
232
+ rb_define_alloc_func(cDeque, deque_alloc);
233
+ rb_define_method(cDeque, "initialize", deque_init, -1);
234
+ rb_define_method(cDeque, "push_front", deque_push_front, 1);
235
+ rb_define_method(cDeque, "push_back", deque_push_back, 1);
236
+ rb_define_method(cDeque, "clear", deque_clear, 0);
237
+ rb_define_method(cDeque, "front", deque_front, 0);
238
+ rb_define_method(cDeque, "back", deque_back, 0);
239
+ rb_define_method(cDeque, "pop_front", deque_pop_front, 0);
240
+ rb_define_method(cDeque, "pop_back", deque_pop_back, 0);
241
+ rb_define_method(cDeque, "size", deque_size, 0);
242
+ rb_define_alias(cDeque, "length", "size");
243
+ rb_define_method(cDeque, "empty?", deque_is_empty, 0);
244
+ rb_define_method(cDeque, "each_forward", deque_each_forward, 0);
245
+ rb_define_method(cDeque, "each_backward", deque_each_backward, 0);
246
+ rb_define_alias(cDeque, "each", "each_forward");
247
+ rb_define_alias(cDeque, "reverse_each", "each_backward");
248
+ rb_include_module(cDeque, rb_eval_string("Enumerable"));
249
+ }
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ extension_name = "CDeque"
3
+ dir_config(extension_name)
4
+ create_makefile(extension_name)
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ extension_name = "CRBTreeMap"
3
+ dir_config(extension_name)
4
+ create_makefile(extension_name)