algorithms 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,16 +0,0 @@
1
- require 'pathname'
2
- require 'benchmark'
3
-
4
- dir = Pathname(__FILE__).dirname.expand_path + 'rbench/'
5
-
6
- require dir + 'runner'
7
- require dir + 'column'
8
- require dir + 'group'
9
- require dir + 'report'
10
- require dir + 'summary'
11
-
12
- module RBench
13
- def self.run(times=1, &block)
14
- Runner.new(times).run(&block)
15
- end
16
- end
@@ -1,26 +0,0 @@
1
- module RBench
2
- class Column
3
- attr_accessor :name, :title, :width, :compare, :default
4
-
5
- def initialize(runner, name, options = {})
6
- @runner = runner
7
- @name = name
8
- @title = options[:title] || (@name == :times ? "" : @name.to_s.upcase)
9
- @width = options[:width] || [@title.length,7].max
10
- @compare = options[:compare]
11
- @default = @compare ? @compare : options[:default]
12
- end
13
-
14
- def to_s(val=title)
15
- str = case val
16
- when Array then "%#{width-1}.2f" % (val[0] / val[1]) + "x"
17
- when Float then "%#{width}.3f" % val
18
- when Integer then "%#{width}.0f" % val
19
- when TrueClass then " "*(width/2.0).floor + "X" + " "*(width/2.0).floor
20
- when String then "%#{width}s" % (val)[0,width]
21
- when Object then " " * width
22
- end
23
- return " #{(str.to_s+" "*width)[0,width]} |"
24
- end
25
- end
26
- end
@@ -1,43 +0,0 @@
1
- module RBench
2
- class Group
3
- self.instance_methods.each do |m|
4
- send(:undef_method, m) unless m =~ /^(__|is_a?|kind_of?|respond_to?|hash|eql?|inspect|instance_eval)/
5
- end
6
-
7
- attr_reader :name, :items, :block, :times
8
-
9
- def initialize(runner, name, times=nil, &block)
10
- @runner = runner
11
- @name = name
12
- @items = []
13
- @block = block
14
- @times = times || @runner.times
15
- end
16
-
17
- def prepare
18
- # This just loops through and spawns the reports, and the summary (if exists)
19
- self.instance_eval(&@block) if @block
20
- # Now we want to make sure that the summary is
21
- @items << @items.shift if @items.first.is_a?(Summary)
22
- end
23
-
24
- def run
25
- # Put a separator with the group-name at the top. puts?
26
- puts @runner.separator(@name)
27
- # Now loop through the items in this group, and run them
28
- @items.each{|item| item.run}
29
- end
30
-
31
- def report(name,times=@times,&block)
32
- @items << Report.new(@runner,self,name,times,&block)
33
- end
34
-
35
- def summary(name)
36
- @items.unshift(Summary.new(@runner,self,name)) unless @items.detect{|i| i.is_a?(Summary)}
37
- end
38
-
39
- def to_s
40
- @runner.separator(@name) << @items.map { |item| item.to_s }.join
41
- end
42
- end
43
- end
@@ -1,53 +0,0 @@
1
- module RBench
2
- class Report
3
- self.instance_methods.each do |m|
4
- send(:undef_method, m) unless m =~ /^(__|is_a?|kind_of?|respond_to?|hash|inspect|instance_eval|eql?)/
5
- end
6
-
7
- attr_reader :name, :cells
8
-
9
- def initialize(runner, group, name, times=nil,&block)
10
- @runner = runner
11
- @group = group
12
- @name = name
13
- @times = (times || runner.times).ceil
14
- @cells = {}
15
- @block = block
16
-
17
- # Setting the default for all cells
18
- runner.columns.each {|c| @cells[c.name] = c.name == :times ? "x#{@times}" : c.default }
19
-
20
- new_self = (class << self; self end)
21
- @runner.columns.each do |column|
22
- new_self.class_eval <<-CLASS
23
- def #{column.name}(val=nil,&block)
24
- @cells[#{column.name.inspect}] = block ? Benchmark.measure { @times.times(&block) }.real : val
25
- end
26
- CLASS
27
- end
28
- end
29
-
30
- def run
31
- # runs the actual benchmarks. If there is only one column, just evaluate the block itself.
32
- if @runner.columns.length == 1
33
- @cells[@runner.columns.first.name] = Benchmark.measure { @times.times(&@block) }.real
34
- else
35
- self.instance_eval(&@block)
36
- end
37
- # puts its row now that it is complete
38
- puts to_s
39
- end
40
-
41
- def to_s
42
- out = "%-#{@runner.desc_width}s" % name
43
- @runner.columns.each do |column|
44
- value = @cells[column.name]
45
- value = @cells.values_at(*value) if value.is_a?(Array)
46
- value = nil if value.is_a?(Array) && value.nitems != 2
47
-
48
- out << column.to_s(value)
49
- end
50
- out << @runner.newline
51
- end
52
- end
53
- end
@@ -1,109 +0,0 @@
1
- module RBench
2
- class Runner
3
- attr_accessor :columns, :items, :times, :width
4
-
5
- def initialize(times)
6
- @width = 0
7
- @times = times
8
- @columns = []
9
- @items = []
10
- end
11
-
12
- def run(&block)
13
-
14
- # initiate all the columns, groups, reports, and summaries on top level.
15
- self.instance_eval(&block)
16
-
17
- # the groups has not run just yet, but when they do, we really only want
18
- # to make them initiate their reports, not run them (just yet)
19
- # when we only have two levels, _every_ report should now be initialized.
20
- @items.each{|item| item.prepare if item.is_a?(Group)}
21
-
22
- # We are putting the summary to the back if its there.
23
- @items << @items.shift if @items.first.is_a?(Summary)
24
-
25
- # if on columns were set, create a default column
26
- column(:results, :title => "Results") if @columns.empty?
27
-
28
- # since we are about to start rendering, we put out the column-header
29
- puts header
30
-
31
- # now we are ready to loop through our items and run!
32
- items.each { |item| item.run if item.respond_to?(:run) }
33
-
34
- # returning self so people can output it in different formats.
35
- self
36
- end
37
-
38
- def format(options={})
39
- @width = options.delete(:width) || @width
40
- end
41
-
42
- def column(name,options={})
43
- @columns << Column.new(self,name,options)
44
- end
45
-
46
- def group(name,times=nil,&block)
47
- @items << Group.new(self,name,times,&block)
48
- end
49
-
50
- def report(name,times=nil,&block)
51
- # create an anonymous group, or add it to the last open group.
52
- group(nil) unless @items.last.is_a?(Group) && !@items.last.block
53
- # now create the report on the last group
54
- @items.last.report(name,times,&block)
55
- end
56
-
57
- def summary(name)
58
- # adding the summary to the front, so it is easier to put it last later.
59
- @items.unshift(Summary.new(self,nil,name)) unless @items.detect{|i| i.is_a?(Summary)}
60
- end
61
-
62
- ##
63
- # convenience-methods
64
- ##
65
-
66
- def groups
67
- @items.select{|item| item.is_a?(Group) }
68
- end
69
-
70
- def reports
71
- # we now want _all_ reports, also those that are part of subgroups
72
- groups.map{|g| g.items.select{|item| item.is_a?(Report) } }.flatten
73
- end
74
-
75
- ##
76
- # for rendering text. pull out in separate module when to_xml and to_html is in place
77
- ##
78
-
79
- def newline
80
- "\n"
81
- end
82
-
83
- def header
84
- " " * desc_width + @columns.map {|c| c.to_s }.join + newline
85
- end
86
-
87
- def desc_width
88
- @desc_width ||= [items.map{|i| (i.items.map{|r| r.name} << i.name) }.flatten.map{|i| i.to_s.length}.max+8,@width-columns_width].max
89
- end
90
-
91
- def columns_width
92
- @columns.inject(0){ |tot,c| tot += (c.to_s.length) }
93
- end
94
-
95
- def width(value=nil)
96
- header.length-1
97
- end
98
-
99
- def separator(title=nil,chr="-",length=width)
100
- title ? chr*2 + title + chr * (width - title.length - 2) : chr * length
101
- end
102
-
103
- def to_s
104
- out = " " * desc_width + @columns.map {|c| c.to_s }.join + newline
105
- out << @items.map {|item| item.to_s}.join
106
- end
107
-
108
- end
109
- end
@@ -1,51 +0,0 @@
1
- module RBench
2
- class Summary
3
- attr_reader :name, :runner, :cells, :items
4
- attr_accessor :lines
5
-
6
- def initialize(runner, group, name)
7
- @runner = runner
8
- @group = group
9
- @name = name
10
- @cells = {} # A hash with keys as columns, and values being the result
11
- @items = []
12
- end
13
-
14
- def run
15
- # maybe add convenience-method to group to. group == runner really.
16
- items = (@group ? @group.items & @runner.reports : @runner.reports)
17
-
18
- rows = items.map{|item| item.cells.values_at(*@runner.columns.map{|c|c.name}) }
19
- rows = rows.pop.zip(*rows)
20
-
21
- @runner.columns.each_with_index do |c,i|
22
- if c.compare
23
- value,comparisons = 0,0
24
- items.each do |item|
25
- v1,v2 = *item.cells.values_at(*c.compare)
26
- if v1.kind_of?(Numeric) && v2.kind_of?(Numeric) && v1 != 0 && v2 != 0
27
- value += v1 / v2
28
- comparisons += 1
29
- end
30
- end
31
- @cells[c.name] = [value,comparisons] if comparisons > 0
32
- elsif c.name != :times
33
- @cells[c.name] = rows[i].compact.select{|r| r.kind_of?(Numeric)}.inject(0){|tot,v| tot += v.to_f }
34
- end
35
- end
36
-
37
- puts to_s
38
- end
39
-
40
- def to_s
41
- out = ""
42
- out << @runner.separator(nil,"=") + @runner.newline unless @group
43
- out << "%-#{@runner.desc_width}s" % name
44
- @runner.columns.each do |column|
45
- value = @cells[column.name]
46
- out << column.to_s( value )
47
- end
48
- out << @runner.newline
49
- end
50
- end
51
- end
@@ -1,205 +0,0 @@
1
- #include "ruby.h"
2
- #include <ctype.h>
3
-
4
- #ifndef RSTRING_PTR
5
- #define RSTRING_PTR(s) (RSTRING(s)->ptr)
6
- #endif
7
-
8
- /* for compatibility with Ruby 1.8.5, which doesn't declare RSTRING_LEN */
9
- #ifndef RSTRING_LEN
10
- #define RSTRING_LEN(s) (RSTRING(s)->len)
11
- #endif
12
-
13
- typedef struct struct_bst_node {
14
- VALUE key;
15
- VALUE data;
16
- struct struct_bst_node *left;
17
- struct struct_bst_node *right;
18
- struct struct_bst_node *parent;
19
- } bst_node;
20
-
21
-
22
- typedef struct struct_bst_head {
23
- bst_node *head;
24
- unsigned int size;
25
- } bst_head;
26
-
27
- static VALUE bst_initialize(VALUE self) {
28
- return self;
29
- }
30
-
31
- static void in_order_display (bst_node *root) {
32
- if (root) {
33
- in_order_display(root->left);
34
- rb_yield(rb_assoc_new(root->key,root->data));
35
- in_order_display(root->right);
36
- }
37
- }
38
-
39
- static int id_compare_operator;
40
-
41
- static int rb_key_compare(VALUE a, VALUE b) {
42
- return FIX2INT(rb_funcall((VALUE) a, id_compare_operator, 1, (VALUE) b));
43
- }
44
-
45
- static void insert_element(bst_node **root,bst_node *newElement) {
46
- bst_node *y = NULL;
47
- bst_node *x = *root;
48
- while (x != NULL) {
49
- y = x;
50
- //if (newElement->key < x->key) x = x->left;
51
- if (rb_key_compare(newElement->key,x->key) < 0) x = x->left;
52
- else x = x->right;
53
- }
54
- newElement->parent = y;
55
- if (y == NULL) *root = newElement;
56
- //else if (newElement->key < y->key) y->left = newElement;
57
- else if (rb_key_compare(newElement->key,y->key) < 0) y->left = newElement;
58
- else y->right = newElement;
59
- }
60
-
61
-
62
- static bst_node *create_element(VALUE key_data,VALUE data) {
63
- bst_node *arbit = malloc(sizeof(bst_node));
64
- arbit->data = data;
65
- arbit->key = key_data;
66
- arbit->left = NULL;
67
- arbit->right = NULL;
68
- arbit->parent = NULL;
69
- return arbit;
70
- }
71
-
72
-
73
- static bst_node *tree_minimum (bst_node *root) {
74
- bst_node *x = root;
75
- while (x->left) x = x->left;
76
- return x;
77
- }
78
-
79
-
80
- static bst_node *tree_maximum (bst_node *root) {
81
- bst_node *x = root;
82
- while (x->right) x = x->right;
83
- return x;
84
- }
85
-
86
- static bst_node *node_successor (bst_node *root,bst_node *x) {
87
- if (x->right) return tree_minimum(x->right);
88
- bst_node *y = x->parent;
89
- while (y && x == y->right) {
90
- x = y;
91
- y = x->parent;
92
- }
93
- return y;
94
- }
95
-
96
-
97
- bst_node *delete_node (bst_node **root,bst_node *tobeDeleted) {
98
- bst_node *y,*x;
99
-
100
- if ((tobeDeleted->left == NULL) || (tobeDeleted->right == NULL)) y = tobeDeleted;
101
- else y = node_successor(*root,tobeDeleted);
102
-
103
- if (y->left) x = y->left;
104
- else x = y->right;
105
-
106
- if (x) x->parent = y->parent;
107
-
108
- if (y->parent == NULL) {
109
- *root = x;
110
- return y;
111
- } else if (y == y->parent->left) {
112
- y->parent->left = x;
113
- } else {
114
- y->parent->right = x;
115
- }
116
-
117
- if (tobeDeleted != y) tobeDeleted->key = y->key;
118
- return y;
119
- }
120
-
121
- bst_node *search_node (bst_node *root,VALUE key) {
122
- bst_node *x = root;
123
- while (x) {
124
- //if (x->key == key) return x;
125
- if (rb_key_compare(x->key,key) == 0) return x;
126
- //else if (key < x->key) x = x->left;
127
- else if (rb_key_compare(key,x->key) < 0) x = x->left;
128
- else x = x->right;
129
- }
130
- return NULL;
131
- }
132
-
133
- void delete_nodes_recur(bst_node *root) {
134
- if(root) {
135
- delete_nodes_recur(root->left);
136
- if(root) free(root);
137
- delete_nodes_recur(root->right);
138
- }
139
- }
140
-
141
- static void bst_free_node(void *p) {
142
- bst_head *headNode = (bst_head *)p;
143
- delete_nodes_recur(headNode->head);
144
- }
145
-
146
- static VALUE bst_alloc(VALUE klass) {
147
- bst_head *headNode = ALLOC(bst_head);
148
- headNode->head = NULL;
149
- headNode->size = 0;
150
- VALUE obj;
151
- obj = Data_Wrap_Struct(klass,NULL,bst_free_node,headNode);
152
- return obj;
153
- }
154
-
155
- static VALUE rb_bst_insert_value(VALUE self,VALUE key,VALUE data) {
156
- bst_head *headNode;
157
- Data_Get_Struct(self,bst_head,headNode);
158
- insert_element(&(headNode->head),create_element(key,data));
159
- headNode->size++;
160
- return self;
161
- }
162
-
163
- /* data structure builds up a stack for traversal, delete can be harmful */
164
- static VALUE rb_bst_each(VALUE self)
165
- {
166
- bst_head *headNode;
167
- Data_Get_Struct(self,bst_head,headNode);
168
- in_order_display(headNode->head);
169
- return Qnil;
170
- }
171
-
172
- static VALUE rb_bst_delete(VALUE self,VALUE keyVal) {
173
- //int key = FIX2INT(keyVal);
174
- bst_head *headNode;
175
- Data_Get_Struct(self,bst_head,headNode);
176
- bst_node *tobeDeleted = search_node(headNode->head,keyVal);
177
- if(tobeDeleted) {
178
- headNode->size = headNode->size - 1;
179
- bst_node *deletedNode = delete_node(&(headNode->head),tobeDeleted);
180
- return deletedNode->data;
181
- } else {
182
- rb_raise(rb_eArgError, "Key was not found");
183
- return Qnil;
184
- }
185
- }
186
-
187
- static VALUE rb_bst_size(VALUE self) {
188
- bst_head *headNode;
189
- Data_Get_Struct(self,bst_head,headNode);
190
- return INT2FIX(headNode->size);
191
- }
192
-
193
- static VALUE mContainers;
194
-
195
- void Init_CBst() {
196
- id_compare_operator = rb_intern("<=>");
197
- mContainers = rb_define_module("Containers");
198
- VALUE cbst_class = rb_define_class_under(mContainers,"CBst",rb_cObject);
199
- rb_define_alloc_func(cbst_class,bst_alloc);
200
- rb_define_method(cbst_class,"initialize",bst_initialize,0);
201
- rb_define_method(cbst_class,"insert",rb_bst_insert_value,2);
202
- rb_define_method(cbst_class,"each", rb_bst_each,0);
203
- rb_define_method(cbst_class,"delete",rb_bst_delete,1);
204
- rb_define_method(cbst_class,"size",rb_bst_size,0);
205
- }