algorithms 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +8 -0
- data/Manifest +9 -14
- data/README.markdown +92 -0
- data/Rakefile +3 -2
- data/algorithms.gemspec +6 -6
- data/benchmarks/deque.rb +17 -0
- data/benchmarks/sorts.rb +3 -2
- data/benchmarks/treemaps.rb +36 -0
- data/ext/containers/deque/deque.c +18 -4
- data/ext/containers/{tree_map → rbtree_map}/extconf.rb +0 -0
- data/ext/containers/{tree_map → rbtree_map}/rbtree.c +42 -12
- data/ext/containers/{bst → splaytree_map}/extconf.rb +1 -1
- data/ext/containers/splaytree_map/splaytree.c +370 -0
- data/lib/algorithms.rb +6 -5
- data/lib/containers/deque.rb +5 -10
- data/lib/containers/splay_tree_map.rb +14 -19
- data/spec/deque_gc_mark_spec.rb +18 -0
- data/spec/heap_spec.rb +110 -103
- data/spec/kd_tree_spec.rb +1 -86
- data/spec/priority_queue_spec.rb +62 -62
- data/spec/rb_tree_map_gc_mark_spec.rb +25 -0
- data/spec/splay_tree_map_spec.rb +26 -26
- metadata +19 -25
- data/README +0 -90
- data/benchmark.rb +0 -51
- data/benchmarks/rbench.rb +0 -16
- data/benchmarks/rbench/column.rb +0 -26
- data/benchmarks/rbench/group.rb +0 -43
- data/benchmarks/rbench/report.rb +0 -53
- data/benchmarks/rbench/runner.rb +0 -109
- data/benchmarks/rbench/summary.rb +0 -51
- data/ext/containers/bst/bst.c +0 -205
- data/lib/graphs/graph.rb +0 -25
- data/spec/bst_spec.rb +0 -31
data/spec/priority_queue_spec.rb
CHANGED
@@ -1,75 +1,75 @@
|
|
1
1
|
$: << File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
|
2
2
|
require 'algorithms'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe Containers::PriorityQueue do
|
5
5
|
before(:each) do
|
6
6
|
@q = Containers::PriorityQueue.new
|
7
7
|
end
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
it "should not return anything" do
|
15
|
-
@q.next.should be_nil
|
16
|
-
@q.pop.should be_nil
|
17
|
-
@q.delete(1).should be_nil
|
18
|
-
@q.has_priority?(1).should be_false
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should give the correct size when adding items" do
|
22
|
-
20.times do |i|
|
23
|
-
@q.size.should eql(i)
|
24
|
-
@q.push(i, i)
|
8
|
+
|
9
|
+
describe "(empty priority queue)" do
|
10
|
+
it "should return 0 for size and be empty" do
|
11
|
+
@q.size.should eql(0)
|
12
|
+
@q.should be_empty
|
25
13
|
end
|
26
|
-
|
27
|
-
|
28
|
-
@q.
|
14
|
+
|
15
|
+
it "should not return anything" do
|
16
|
+
@q.next.should be_nil
|
17
|
+
@q.pop.should be_nil
|
18
|
+
@q.delete(1).should be_nil
|
19
|
+
@q.has_priority?(1).should be_false
|
29
20
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
21
|
+
|
22
|
+
it "should give the correct size when adding items" do
|
23
|
+
20.times do |i|
|
24
|
+
@q.size.should eql(i)
|
25
|
+
@q.push(i, i)
|
26
|
+
end
|
27
|
+
10.times do |i|
|
28
|
+
@q.size.should eql(20-i)
|
29
|
+
@q.pop
|
30
|
+
end
|
31
|
+
10.times do |i|
|
32
|
+
@q.size.should eql(i+10)
|
33
|
+
@q.push(i, i)
|
34
|
+
end
|
35
|
+
@q.delete(5)
|
36
|
+
@q.size.should eql(19)
|
33
37
|
end
|
34
|
-
@q.delete(5)
|
35
|
-
@q.size.should eql(19)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe "non-empty priority queue" do
|
40
|
-
before(:each) do
|
41
|
-
@q = Containers::PriorityQueue.new
|
42
|
-
@q.push("Alaska", 50)
|
43
|
-
@q.push("Delaware", 30)
|
44
|
-
@q.push("Georgia", 35)
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should next/pop the highest priority" do
|
48
|
-
@q.next.should eql("Alaska")
|
49
|
-
@q.size.should eql(3)
|
50
|
-
@q.pop.should eql("Alaska")
|
51
|
-
@q.size.should eql(2)
|
52
38
|
end
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
@q.
|
39
|
+
|
40
|
+
describe "(non-empty priority queue)" do
|
41
|
+
before(:each) do
|
42
|
+
@q.push("Alaska", 50)
|
43
|
+
@q.push("Delaware", 30)
|
44
|
+
@q.push("Georgia", 35)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should next/pop the highest priority" do
|
48
|
+
@q.next.should eql("Alaska")
|
49
|
+
@q.size.should eql(3)
|
50
|
+
@q.pop.should eql("Alaska")
|
51
|
+
@q.size.should eql(2)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should not be empty" do
|
55
|
+
@q.should_not be_empty
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should has_priority? priorities it has" do
|
59
|
+
@q.has_priority?(50).should be_true
|
60
|
+
@q.has_priority?(10).should be_false
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return nil after popping everything" do
|
64
|
+
3.times do
|
65
|
+
@q.pop
|
66
|
+
end
|
67
|
+
@q.pop.should be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should delete things it has and not things it doesn't" do
|
71
|
+
@q.delete(50).should eql("Alaska")
|
72
|
+
@q.delete(10).should eql(nil)
|
66
73
|
end
|
67
|
-
@q.pop.should be_nil
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should delete things it has and not things it doesn't" do
|
71
|
-
@q.delete(50).should eql("Alaska")
|
72
|
-
@q.delete(10).should eql(nil)
|
73
74
|
end
|
74
|
-
|
75
75
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
$: << File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
|
2
|
+
require 'algorithms'
|
3
|
+
|
4
|
+
if defined? Containers::CRBTreeMap
|
5
|
+
describe "CRBTreeMap" do
|
6
|
+
it "should mark ruby object references" do
|
7
|
+
anon_key_class = Class.new do
|
8
|
+
attr :value
|
9
|
+
def initialize(x); @value = x; end
|
10
|
+
def <=>(other); value <=> other.value; end
|
11
|
+
end
|
12
|
+
anon_val_class = Class.new
|
13
|
+
@tree = Containers::CRBTreeMap.new
|
14
|
+
100.times { |x| @tree[anon_key_class.new(x)] = anon_val_class.new }
|
15
|
+
# Mark and sweep
|
16
|
+
ObjectSpace.garbage_collect
|
17
|
+
# Check if any instances were swept
|
18
|
+
count = 0
|
19
|
+
ObjectSpace.each_object(anon_key_class) { |x| count += 1 }
|
20
|
+
count.should eql(100)
|
21
|
+
ObjectSpace.each_object(anon_val_class) { |x| count += 1 }
|
22
|
+
count.should eql(200)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/splay_tree_map_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
$: << File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
|
2
2
|
require 'algorithms'
|
3
3
|
|
4
|
-
describe "
|
4
|
+
describe "empty splaytree", :shared => true do
|
5
5
|
it "should let you push stuff in" do
|
6
6
|
100.times { |x| @tree[x] = x }
|
7
7
|
@tree.size.should eql(100)
|
@@ -21,7 +21,7 @@ describe "(empty splay)", :shared => true do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
describe "
|
24
|
+
describe "non-empty splaytree", :shared => true do
|
25
25
|
before(:each) do
|
26
26
|
@num_items = 100
|
27
27
|
@random_array = []
|
@@ -69,34 +69,34 @@ describe "(non-empty splay)", :shared => true do
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
# end
|
86
|
-
# end
|
72
|
+
describe "empty splaytreemap" do
|
73
|
+
before(:each) do
|
74
|
+
@tree = Containers::RubySplayTreeMap.new
|
75
|
+
end
|
76
|
+
it_should_behave_like "empty splaytree"
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "full splaytreemap" do
|
80
|
+
before(:each) do
|
81
|
+
@tree = Containers::RubySplayTreeMap.new
|
82
|
+
end
|
83
|
+
it_should_behave_like "non-empty splaytree"
|
84
|
+
end
|
87
85
|
|
88
|
-
|
89
|
-
|
86
|
+
begin
|
87
|
+
Containers::CSplayTreeMap
|
88
|
+
describe "empty csplaytreemap" do
|
90
89
|
before(:each) do
|
91
|
-
@tree = Containers::
|
90
|
+
@tree = Containers::CSplayTreeMap.new
|
92
91
|
end
|
93
|
-
it_should_behave_like "
|
92
|
+
it_should_behave_like "empty splaytree"
|
94
93
|
end
|
95
|
-
|
96
|
-
describe "full
|
94
|
+
|
95
|
+
describe "full csplaytreemap" do
|
97
96
|
before(:each) do
|
98
|
-
@tree = Containers::
|
97
|
+
@tree = Containers::CSplayTreeMap.new
|
99
98
|
end
|
100
|
-
it_should_behave_like "
|
99
|
+
it_should_behave_like "non-empty splaytree"
|
101
100
|
end
|
102
|
-
|
101
|
+
rescue Exception
|
102
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: algorithms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kanwei Li
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-03-29 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -18,16 +18,16 @@ email: kanwei@gmail.com
|
|
18
18
|
executables: []
|
19
19
|
|
20
20
|
extensions:
|
21
|
-
- ext/containers/bst/extconf.rb
|
22
21
|
- ext/containers/deque/extconf.rb
|
23
|
-
- ext/containers/
|
22
|
+
- ext/containers/rbtree_map/extconf.rb
|
23
|
+
- ext/containers/splaytree_map/extconf.rb
|
24
24
|
extra_rdoc_files:
|
25
|
-
- ext/containers/bst/bst.c
|
26
|
-
- ext/containers/bst/extconf.rb
|
27
25
|
- ext/containers/deque/deque.c
|
28
26
|
- ext/containers/deque/extconf.rb
|
29
|
-
- ext/containers/
|
30
|
-
- ext/containers/
|
27
|
+
- ext/containers/rbtree_map/extconf.rb
|
28
|
+
- ext/containers/rbtree_map/rbtree.c
|
29
|
+
- ext/containers/splaytree_map/extconf.rb
|
30
|
+
- ext/containers/splaytree_map/splaytree.c
|
31
31
|
- lib/algorithms/search.rb
|
32
32
|
- lib/algorithms/sort.rb
|
33
33
|
- lib/algorithms.rb
|
@@ -41,24 +41,18 @@ extra_rdoc_files:
|
|
41
41
|
- lib/containers/stack.rb
|
42
42
|
- lib/containers/suffix_array.rb
|
43
43
|
- lib/containers/trie.rb
|
44
|
-
-
|
45
|
-
- README
|
44
|
+
- README.markdown
|
46
45
|
files:
|
47
46
|
- algorithms.gemspec
|
48
|
-
-
|
49
|
-
- benchmarks/rbench/column.rb
|
50
|
-
- benchmarks/rbench/group.rb
|
51
|
-
- benchmarks/rbench/report.rb
|
52
|
-
- benchmarks/rbench/runner.rb
|
53
|
-
- benchmarks/rbench/summary.rb
|
54
|
-
- benchmarks/rbench.rb
|
47
|
+
- benchmarks/deque.rb
|
55
48
|
- benchmarks/sorts.rb
|
56
|
-
-
|
57
|
-
- ext/containers/bst/extconf.rb
|
49
|
+
- benchmarks/treemaps.rb
|
58
50
|
- ext/containers/deque/deque.c
|
59
51
|
- ext/containers/deque/extconf.rb
|
60
|
-
- ext/containers/
|
61
|
-
- ext/containers/
|
52
|
+
- ext/containers/rbtree_map/extconf.rb
|
53
|
+
- ext/containers/rbtree_map/rbtree.c
|
54
|
+
- ext/containers/splaytree_map/extconf.rb
|
55
|
+
- ext/containers/splaytree_map/splaytree.c
|
62
56
|
- History.txt
|
63
57
|
- lib/algorithms/search.rb
|
64
58
|
- lib/algorithms/sort.rb
|
@@ -73,16 +67,16 @@ files:
|
|
73
67
|
- lib/containers/stack.rb
|
74
68
|
- lib/containers/suffix_array.rb
|
75
69
|
- lib/containers/trie.rb
|
76
|
-
- lib/graphs/graph.rb
|
77
70
|
- Manifest
|
78
71
|
- Rakefile
|
79
|
-
- README
|
80
|
-
- spec/
|
72
|
+
- README.markdown
|
73
|
+
- spec/deque_gc_mark_spec.rb
|
81
74
|
- spec/deque_spec.rb
|
82
75
|
- spec/heap_spec.rb
|
83
76
|
- spec/kd_tree_spec.rb
|
84
77
|
- spec/priority_queue_spec.rb
|
85
78
|
- spec/queue_spec.rb
|
79
|
+
- spec/rb_tree_map_gc_mark_spec.rb
|
86
80
|
- spec/rb_tree_map_spec.rb
|
87
81
|
- spec/search_spec.rb
|
88
82
|
- spec/sort_spec.rb
|
@@ -99,7 +93,7 @@ rdoc_options:
|
|
99
93
|
- --title
|
100
94
|
- Algorithms
|
101
95
|
- --main
|
102
|
-
- README
|
96
|
+
- README.markdown
|
103
97
|
require_paths:
|
104
98
|
- lib
|
105
99
|
- ext
|
data/README
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
= algorithms
|
2
|
-
|
3
|
-
* http://rubyforge.org/projects/algorithms/
|
4
|
-
* Documentation: http://algorithms.rubyforge.org/
|
5
|
-
|
6
|
-
== DESCRIPTION:
|
7
|
-
|
8
|
-
This is a Google Summer of Code 2008 project
|
9
|
-
|
10
|
-
Written by Kanwei Li, mentored by Austin Ziegler
|
11
|
-
|
12
|
-
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/PROBLEMS:
|
22
|
-
|
23
|
-
Done so far:
|
24
|
-
* Heaps - Containers::Heap, Containers::MaxHeap, Containers::MinHeap
|
25
|
-
* Priority Queue - Containers::PriorityQueue
|
26
|
-
* Stack - Containers::Stack
|
27
|
-
* Queue - Containers::Queue
|
28
|
-
* Deque - Containers::Deque, Containers::CDeque (C extension), Containers::RubyDeque
|
29
|
-
* Red-Black Trees - Containers::RBTreeMap, Containers::CRBTreeMap (C extension), Containers::RubyRBTreeMap
|
30
|
-
* Splay Trees - Containers::SplayTreeMap
|
31
|
-
* Tries - Containers::Trie
|
32
|
-
* Suffix Array - Containers::SuffixArray
|
33
|
-
|
34
|
-
* Search algorithms
|
35
|
-
- Binary Search - Algorithms::Search.binary_search
|
36
|
-
- Knuth-Morris-Pratt - Algorithms::Search.kmp_search
|
37
|
-
* Sort algorithms
|
38
|
-
- Bubble sort - Algorithms::Sort.bubble_sort
|
39
|
-
- Comb sort - Algorithms::Sort.comb_sort
|
40
|
-
- Selection sort - Algorithms::Sort.selection_sort
|
41
|
-
- Heapsort - Algorithms::Sort.heapsort
|
42
|
-
- Insertion sort - Algorithms::Sort.insertion_sort
|
43
|
-
- Shell sort - Algorithms::Sort.shell_sort
|
44
|
-
- Quicksort - Algorithms::Sort.quicksort
|
45
|
-
- Mergesort - Algorithms::Sort.mergesort
|
46
|
-
|
47
|
-
== SYNOPSIS:
|
48
|
-
|
49
|
-
require 'rubygems'
|
50
|
-
require 'algorithms'
|
51
|
-
|
52
|
-
max_heap = Containers::MaxHeap.new
|
53
|
-
|
54
|
-
# To not have to type "Containers::" before each class, use:
|
55
|
-
include Containers
|
56
|
-
max_heap = MaxHeap.new
|
57
|
-
|
58
|
-
== REQUIREMENTS:
|
59
|
-
|
60
|
-
* Ruby 1.8 compatible Ruby, or Ruby 1.9
|
61
|
-
* C compiler for extensions (optional)
|
62
|
-
|
63
|
-
== INSTALL:
|
64
|
-
|
65
|
-
* sudo gem install
|
66
|
-
|
67
|
-
== LICENSE:
|
68
|
-
|
69
|
-
(The MIT License)
|
70
|
-
|
71
|
-
Algorithms and Containers project is Copyright (c) 2008 Kanwei Li
|
72
|
-
|
73
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
74
|
-
a copy of this software and associated documentation files (the
|
75
|
-
'Software'), to deal in the Software without restriction, including
|
76
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
77
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
78
|
-
permit persons to whom the Software is furnished to do so, subject to
|
79
|
-
the following conditions:
|
80
|
-
|
81
|
-
The above copyright notice and this permission notice shall be
|
82
|
-
included in all copies or substantial portions of the Software.
|
83
|
-
|
84
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
85
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
86
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
87
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
88
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
89
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
90
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/benchmark.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
# :nodoc: all
|
2
|
-
$: << File.join(File.expand_path(File.dirname(__FILE__)), 'lib')
|
3
|
-
require 'algorithms'
|
4
|
-
|
5
|
-
require 'benchmark'
|
6
|
-
include Benchmark
|
7
|
-
|
8
|
-
# Benchmark heap
|
9
|
-
@random_array = []
|
10
|
-
@num_items = 10000
|
11
|
-
@num_items.times { |x| @random_array << rand(@num_items) }
|
12
|
-
# @heap = Containers::MaxHeap.new(@random_array)
|
13
|
-
#
|
14
|
-
# benchmark do |bench|
|
15
|
-
# bench.report("Array#max:\t ") do
|
16
|
-
# @num_items.times { @random_array.delete_at(@random_array.index(@random_array.max)) }
|
17
|
-
# end
|
18
|
-
# bench.report("MaxHeap:\t ") do
|
19
|
-
# @num_items.times { @heap.max! }
|
20
|
-
# end
|
21
|
-
# end
|
22
|
-
|
23
|
-
# Benchmark Deque
|
24
|
-
deque = Containers::RubyDeque.new
|
25
|
-
array = []
|
26
|
-
benchmark do |bench|
|
27
|
-
bench.report("Array:\t ") { 1000000.times { |x| array << x } }
|
28
|
-
bench.report("Deque:\t ") { 1000000.times { |x| deque.push_back(x) } }
|
29
|
-
end
|
30
|
-
|
31
|
-
# Benchmark Search trees
|
32
|
-
@rb_tree = Containers::RubyRBTreeMap.new
|
33
|
-
@splay_tree = Containers::SplayTreeMap.new
|
34
|
-
@hash = Hash.new
|
35
|
-
|
36
|
-
benchmark do |bench|
|
37
|
-
puts "\nInsertion"
|
38
|
-
bench.report("RBTree: \t") { @random_array.each { |x| @rb_tree[x] = x } }
|
39
|
-
bench.report("SplayTree: \t") { @random_array.each { |x| @splay_tree[x] = x } }
|
40
|
-
bench.report("Hash: \t\t") { @hash.each { |x| @hash[x] = x } }
|
41
|
-
|
42
|
-
puts "\nTest has_key?"
|
43
|
-
bench.report("RBTree: \t") { @num_items.times { |n| @rb_tree.has_key?(n) } }
|
44
|
-
bench.report("SplayTree: \t") { @num_items.times { |n| @splay_tree.has_key?(n) } }
|
45
|
-
bench.report("Hash: \t\t") { @num_items.times { |n| @hash.has_key?(n) } }
|
46
|
-
|
47
|
-
puts "\nSorted order"
|
48
|
-
bench.report("RBTree: \t") { @rb_tree.each { |k, v| k } }
|
49
|
-
bench.report("SplayTree: \t") { @splay_tree.each { |k, v| k } }
|
50
|
-
bench.report("Hash: \t\t") { @hash.sort.each { |k, v| k } }
|
51
|
-
end
|