algorithms 0.3.0-jruby

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 (44) hide show
  1. data/History.txt +172 -0
  2. data/Manifest +43 -0
  3. data/README.markdown +93 -0
  4. data/Rakefile +31 -0
  5. data/algorithms.gemspec +33 -0
  6. data/benchmarks/deque.rb +17 -0
  7. data/benchmarks/sorts.rb +34 -0
  8. data/benchmarks/treemaps.rb +51 -0
  9. data/ext/containers/deque/deque.c +247 -0
  10. data/ext/containers/deque/extconf.rb +4 -0
  11. data/ext/containers/rbtree_map/extconf.rb +4 -0
  12. data/ext/containers/rbtree_map/rbtree.c +498 -0
  13. data/ext/containers/splaytree_map/extconf.rb +4 -0
  14. data/ext/containers/splaytree_map/splaytree.c +419 -0
  15. data/lib/algorithms.rb +68 -0
  16. data/lib/algorithms/search.rb +84 -0
  17. data/lib/algorithms/sort.rb +238 -0
  18. data/lib/containers/deque.rb +171 -0
  19. data/lib/containers/heap.rb +486 -0
  20. data/lib/containers/kd_tree.rb +110 -0
  21. data/lib/containers/priority_queue.rb +113 -0
  22. data/lib/containers/queue.rb +68 -0
  23. data/lib/containers/rb_tree_map.rb +398 -0
  24. data/lib/containers/splay_tree_map.rb +269 -0
  25. data/lib/containers/stack.rb +67 -0
  26. data/lib/containers/suffix_array.rb +68 -0
  27. data/lib/containers/trie.rb +182 -0
  28. data/spec/deque_gc_mark_spec.rb +18 -0
  29. data/spec/deque_spec.rb +108 -0
  30. data/spec/heap_spec.rb +126 -0
  31. data/spec/kd_expected_out.txt +10000 -0
  32. data/spec/kd_test_in.txt +10000 -0
  33. data/spec/kd_tree_spec.rb +34 -0
  34. data/spec/map_gc_mark_spec.rb +27 -0
  35. data/spec/priority_queue_spec.rb +75 -0
  36. data/spec/queue_spec.rb +61 -0
  37. data/spec/rb_tree_map_spec.rb +123 -0
  38. data/spec/search_spec.rb +28 -0
  39. data/spec/sort_spec.rb +28 -0
  40. data/spec/splay_tree_map_spec.rb +106 -0
  41. data/spec/stack_spec.rb +60 -0
  42. data/spec/suffix_array_spec.rb +40 -0
  43. data/spec/trie_spec.rb +59 -0
  44. metadata +122 -0
@@ -0,0 +1,172 @@
1
+ === April 3, 2009
2
+
3
+ * Finished C refactorization of SplayTree
4
+
5
+ === March 28, 2009
6
+
7
+ * Implemented SplayTree in C
8
+ * Made recursively_free_nodes methods static to fix a SEGFAULT
9
+ * Improved CBst
10
+ * Moved to Markdown for README
11
+ * 0.2.0 release
12
+
13
+ === January 19, 2009
14
+
15
+ * kd-tree for points in multi-dimensional space
16
+
17
+ === November 25, 2008
18
+
19
+ * Checked in gnufied's C BST
20
+
21
+ === November 13, 2008
22
+
23
+ * Removed #each for Hash and Priority Queue (Feature)
24
+
25
+ === September 15, 2008
26
+
27
+ * Added comb sort
28
+ * Benchmark work on sorting algorithms
29
+
30
+ === September 1, 2008
31
+
32
+ * Switched to Hanna rdoc template
33
+ * RBTree#isred now private
34
+
35
+ === August 20, 2008
36
+
37
+ * Implemented Knuth-Morris-Pratt substring algorithm
38
+
39
+ === August 15, 2008
40
+
41
+ * Updated README to reflect progress
42
+
43
+ === August 10, 2008
44
+
45
+ * Implemented mergesort, insertion_sort, shell_sort, quicksort
46
+
47
+ === August 8, 2008
48
+
49
+ * Implemented bubble_sort, selection_sort, heapsort
50
+
51
+ === August 5, 2008
52
+
53
+ * Started Algorithms portion
54
+ * Implemented Search#binary_search
55
+
56
+ === July 20, 2008
57
+
58
+ * Iterate over trees iteratively instead of recursively
59
+ * Implemented Deque in C
60
+
61
+ === July 15, 2008
62
+
63
+ * Refactored namespaces, thank you Austin Ziegler!
64
+
65
+ === July 14, 2008
66
+
67
+ * Use alias_method instead of alias
68
+ * Found and fixed RBTree#delete bug (finally!)
69
+ * Refactored Trie, SuffixArray, SplayTreeMap
70
+
71
+ === July 13, 2008
72
+
73
+ * Refactored Deque
74
+ * Implemented Deque#reverse_each (like Array's)
75
+
76
+ === July 12, 2008
77
+
78
+ * Reformatted some specs to be more idiomatic (Thank you Federico Builes)
79
+
80
+ === July 10, 2008
81
+
82
+ * Added algorithm complexity information for all Containers
83
+ * Implemented Trie for string representation
84
+ * Implmented SuffixArray for fast substring search
85
+ * Fixed memory leak in CRBTree
86
+ * Updated Manifest and algorithms.rb to match progress
87
+
88
+ === July 9, 2008
89
+
90
+ * Implemented Deque
91
+ * Stack and Queue now use Deque
92
+ * Fixed issues with CRBTree's #empty? and delete methods
93
+
94
+ === July 8, 2008
95
+
96
+ * Can now iterate over a heap
97
+ * Renamed #contains_key -> has_key? since it's more idiomatic
98
+ * Implented #change_key and #delete for Heap
99
+ * Priority Queue is now implemented with the new Fibonacci Heap
100
+ * Removed old Priority Queue code as a result
101
+ * Heap: fixed #delete bug not checking if item exists, #has_key? bug
102
+ for not returning boolean
103
+ * Heap: value field is now optional and defaults to the key if not specified
104
+ * More refactoring of RBTreeMap (both Ruby and C)
105
+
106
+ === July 7, 2008
107
+
108
+ * Heap is now implemented with a Fibonacci Heap, not a binomial heap
109
+
110
+ === July 4, 2008
111
+
112
+ * Implemented SplayTreeMap
113
+ * Heap now uses kind_of? to check for other heaps when doing #merge
114
+ * Renamed some Heap methods for consistency with the rest of the library
115
+ * RBTreeMap#contains? -> contains_key?
116
+ * Refactored RBTreeMap to be more object-oriented
117
+ * More documentation for RBTreeMap
118
+
119
+ === July 3, 2008
120
+
121
+ * Added documentation for Stack and Queue
122
+
123
+ === June 24, 2008
124
+
125
+ * Imported Brian Amberg's priority queue implementation
126
+ * Now uses Echoe to build gem
127
+ * Gem builds for the first time
128
+
129
+ === June 18, 2008
130
+
131
+ * Can now enumerate over RBTreeMap
132
+
133
+ === June 17, 2008
134
+
135
+ * RBTreemap#delete now returns deleted value
136
+ * Added delete method to C implementation
137
+
138
+ === June 16, 2008
139
+
140
+ * Implemented delete methods for RBTreeMap
141
+
142
+ === June 14, 2008
143
+
144
+ * Renamed the data structures module to "Containers"
145
+ * Removed dependence on stdbool.h
146
+ * Renamed RBTree to RBTreeMap
147
+
148
+ === June 13, 2008
149
+
150
+ * Implemented Sedgewick's Left Leaning Red Black Tree in C!
151
+
152
+ === June 12, 2008
153
+
154
+ * Implemented Sedgewick's Left Leaning Red Black Tree
155
+
156
+ === June 10, 2008
157
+
158
+ * Implemented merge! for other heaps and heap initialization from an array
159
+ * Implemented Queue
160
+
161
+ === June 9, 2008
162
+
163
+ * Finished binomial heap implementation
164
+
165
+ === June 8, 2008
166
+
167
+ * Added Stack
168
+ * Working on heap
169
+
170
+ === April 20
171
+
172
+ * Accepted to Google Summer of Code!
@@ -0,0 +1,43 @@
1
+ History.txt
2
+ Manifest
3
+ README.markdown
4
+ Rakefile
5
+ algorithms.gemspec
6
+ benchmarks/deque.rb
7
+ benchmarks/sorts.rb
8
+ benchmarks/treemaps.rb
9
+ ext/containers/deque/deque.c
10
+ ext/containers/deque/extconf.rb
11
+ ext/containers/rbtree_map/extconf.rb
12
+ ext/containers/rbtree_map/rbtree.c
13
+ ext/containers/splaytree_map/extconf.rb
14
+ ext/containers/splaytree_map/splaytree.c
15
+ lib/algorithms.rb
16
+ lib/algorithms/search.rb
17
+ lib/algorithms/sort.rb
18
+ lib/containers/deque.rb
19
+ lib/containers/heap.rb
20
+ lib/containers/kd_tree.rb
21
+ lib/containers/priority_queue.rb
22
+ lib/containers/queue.rb
23
+ lib/containers/rb_tree_map.rb
24
+ lib/containers/splay_tree_map.rb
25
+ lib/containers/stack.rb
26
+ lib/containers/suffix_array.rb
27
+ lib/containers/trie.rb
28
+ spec/deque_gc_mark_spec.rb
29
+ spec/deque_spec.rb
30
+ spec/heap_spec.rb
31
+ spec/kd_expected_out.txt
32
+ spec/kd_test_in.txt
33
+ spec/kd_tree_spec.rb
34
+ spec/map_gc_mark_spec.rb
35
+ spec/priority_queue_spec.rb
36
+ spec/queue_spec.rb
37
+ spec/rb_tree_map_spec.rb
38
+ spec/search_spec.rb
39
+ spec/sort_spec.rb
40
+ spec/splay_tree_map_spec.rb
41
+ spec/stack_spec.rb
42
+ spec/suffix_array_spec.rb
43
+ spec/trie_spec.rb
@@ -0,0 +1,93 @@
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 Containers::Heap, Containers::MaxHeap, Containers::MinHeap
26
+ * Priority Queue Containers::PriorityQueue
27
+ * Deque Containers::Deque, Containers::CDeque (C extension), Containers::RubyDeque
28
+ * Stack Containers::Stack (uses Deque)
29
+ * Queue Containers::Queue (uses Deque)
30
+ * Red-Black Trees Containers::RBTreeMap, Containers::CRBTreeMap (C extension), Containers::RubyRBTreeMap
31
+ * Splay Trees Containers::SplayTreeMap, Containers::CSplayTreeMap (C extension), Containers::RubySplayTreeMap
32
+ * Tries Containers::Trie
33
+ * Suffix Array Containers::SuffixArray
34
+ * kd Tree Containers::KDTree
35
+
36
+ * Search algorithms
37
+ - Binary Search Algorithms::Search.binary_search
38
+ - Knuth-Morris-Pratt Algorithms::Search.kmp_search
39
+ * Sort algorithms
40
+ - Bubble sort Algorithms::Sort.bubble_sort
41
+ - Comb sort Algorithms::Sort.comb_sort
42
+ - Selection sort Algorithms::Sort.selection_sort
43
+ - Heapsort Algorithms::Sort.heapsort
44
+ - Insertion sort Algorithms::Sort.insertion_sort
45
+ - Shell sort Algorithms::Sort.shell_sort
46
+ - Quicksort Algorithms::Sort.quicksort
47
+ - Mergesort Algorithms::Sort.mergesort
48
+
49
+ ## SYNOPSIS:
50
+
51
+ require 'rubygems'
52
+ require 'algorithms'
53
+
54
+ max_heap = Containers::MaxHeap.new
55
+
56
+ # To not have to type "Containers::" before each class, use:
57
+ include Containers
58
+ max_heap = MaxHeap.new
59
+
60
+
61
+ ## REQUIREMENTS:
62
+
63
+ * Ruby 1.8 compatible Ruby, or Ruby 1.9
64
+ * C compiler for C extensions (optional, but very much recommended for vast performance benefits)
65
+
66
+ ## INSTALL:
67
+
68
+ * sudo gem install algorithms
69
+
70
+ ## LICENSE:
71
+
72
+ (The MIT License)
73
+
74
+ Algorithms and Containers project is Copyright (c) 2009 Kanwei Li
75
+
76
+ Permission is hereby granted, free of charge, to any person obtaining
77
+ a copy of this software and associated documentation files (the
78
+ 'Software'), to deal in the Software without restriction, including
79
+ without limitation the rights to use, copy, modify, merge, publish,
80
+ distribute, sublicense, and/or sell copies of the Software, and to
81
+ permit persons to whom the Software is furnished to do so, subject to
82
+ the following conditions:
83
+
84
+ The above copyright notice and this permission notice shall be
85
+ included in all copies or substantial portions of the Software.
86
+
87
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
88
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
89
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
90
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
91
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
92
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
93
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+ require 'echoe'
3
+
4
+ Echoe.new('algorithms') do |p|
5
+ p.author = 'Kanwei Li'
6
+ p.email = 'kanwei@gmail.com'
7
+ p.summary = 'A library of algorithms and containers.'
8
+ p.url = 'http://rubyforge.org/projects/algorithms/'
9
+ p.version = "0.3.0"
10
+ p.runtime_dependencies = []
11
+ end
12
+
13
+ task :default => :spec
14
+
15
+ task :spec do
16
+ sh "spec spec/*.rb --color"
17
+ end
18
+
19
+ task :push do
20
+ sh "git push" # Rubyforge
21
+ sh "git push --tags" # Rubyforge
22
+ sh "git push gh" # Github
23
+ sh "git push gh --tags" # Github
24
+ end
25
+
26
+ task :hanna do
27
+ sh "rm -fr doc"
28
+ sh "hanna -SN lib/ -m Algorithms"
29
+ sh "scp -rq doc/* kanwei@rubyforge.org:/var/www/gforge-projects/algorithms"
30
+ end
31
+
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{algorithms}
5
+ s.version = "0.3.0"
6
+ s.platform = %q{jruby}
7
+
8
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
9
+ s.authors = ["Kanwei Li"]
10
+ s.date = %q{2009-11-16}
11
+ s.description = %q{A library of algorithms and containers.}
12
+ s.email = %q{kanwei@gmail.com}
13
+ s.extensions = ["ext/containers/deque/extconf.rb", "ext/containers/rbtree_map/extconf.rb", "ext/containers/splaytree_map/extconf.rb"]
14
+ s.extra_rdoc_files = ["README.markdown", "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/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"]
15
+ s.files = ["History.txt", "Manifest", "README.markdown", "Rakefile", "algorithms.gemspec", "benchmarks/deque.rb", "benchmarks/sorts.rb", "benchmarks/treemaps.rb", "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/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/suffix_array_spec.rb", "spec/trie_spec.rb"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://rubyforge.org/projects/algorithms/}
18
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Algorithms", "--main", "README.markdown"]
19
+ s.require_paths = ["lib", "ext"]
20
+ s.rubyforge_project = %q{algorithms}
21
+ s.rubygems_version = %q{1.3.1}
22
+ s.summary = %q{A library of algorithms and containers.}
23
+
24
+ if s.respond_to? :specification_version then
25
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
+ s.specification_version = 2
27
+
28
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
29
+ else
30
+ end
31
+ else
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ $: << File.join(File.expand_path(File.dirname(__FILE__)), '../lib')
2
+ require 'algorithms'
3
+ include Algorithms
4
+
5
+ require 'rubygems'
6
+ require 'rbench'
7
+
8
+ RBench.run(2) do
9
+ %w(array deque).each { |s| self.send(:column, s.intern) }
10
+ deque = Containers::Deque.new
11
+ array = []
12
+
13
+ report "Insertion at end" do
14
+ array { 1000000.times { |x| array << x } }
15
+ deque { 1000000.times { |x| deque.push_back(x) } }
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ $: << File.join(File.expand_path(File.dirname(__FILE__)), '../lib')
2
+ require 'algorithms'
3
+ include Algorithms
4
+
5
+ require 'rubygems'
6
+ require 'rbench'
7
+
8
+ RBench.run(5) do
9
+
10
+ sorts = %w(ruby comb_sort heapsort insertion_sort shell_sort quicksort mergesort)
11
+ sorts.each { |sort| self.send(:column, sort.intern) }
12
+
13
+ n = 1000
14
+
15
+ proc = lambda { |scope, ary|
16
+ scope.ruby { ary.dup.sort }
17
+ scope.comb_sort { Sort.comb_sort(ary.dup) }
18
+ scope.heapsort { Sort.heapsort(ary.dup) }
19
+ scope.insertion_sort { Sort.insertion_sort(ary.dup) }
20
+ scope.shell_sort { Sort.shell_sort(ary.dup) }
21
+ scope.quicksort { Sort.quicksort(ary.dup) }
22
+ scope.mergesort { Sort.mergesort(ary.dup) }
23
+ }
24
+
25
+ report "Already sorted" do
26
+ sorted_array = Array.new(n) { rand(n) }.sort
27
+ proc.call(self, sorted_array)
28
+ end
29
+
30
+ report "Random" do
31
+ random_array = Array.new(n) { rand(n) }
32
+ proc.call(self, random_array)
33
+ end
34
+ end
@@ -0,0 +1,51 @@
1
+ $: << File.join(File.expand_path(File.dirname(__FILE__)), '../lib')
2
+ require 'algorithms'
3
+ include Containers
4
+
5
+ require 'rubygems'
6
+ require 'rbench'
7
+
8
+ RBench.run(2) do
9
+ trees = %w(hash rbtree splaytree)
10
+ trees.each { |tree| self.send(:column, tree.intern) }
11
+
12
+ rbtree = RBTreeMap.new
13
+ splaytree = SplayTreeMap.new
14
+ hash = Hash.new
15
+
16
+ random_array = Array.new(300000) { |i| rand(i) }
17
+
18
+ report "Insertion" do
19
+ rbtree { random_array.each_with_index { |x,index| rbtree[index] = x } }
20
+ splaytree { random_array.each_with_index { |x,index| splaytree[index] = x } }
21
+ hash { random_array.each_with_index { |x,index| hash[index] = x } }
22
+ end
23
+
24
+ report "has_key? (linear order)" do
25
+ rbtree { random_array.each { |n| rbtree.has_key?(n) } }
26
+ splaytree { random_array.each { |n| splaytree.has_key?(n) } }
27
+ hash { random_array.each { |n| hash.has_key?(n) } }
28
+ end
29
+
30
+ report "Lookup in sorted order" do
31
+ rbtree { rbtree.each { |k, v| k } }
32
+ splaytree { splaytree.each { |k, v| k } }
33
+ hash { hash.sort.each { |k, v| k } }
34
+
35
+ # a1, a2, a3 = [], [], []
36
+ # rbtree.each { |k, v| a1 << k }
37
+ # splaytree.each { |k, v| a2 << k }
38
+ # hash.sort.each { |k, v| a3 << k }
39
+ #
40
+ # puts "Lookup correct" if a1 == a2 && a1 == a3
41
+ end
42
+
43
+ report "Random lookups in a smaller subset" do
44
+ select_subset = random_array[0..random_array.size/20] # 5%
45
+ size = select_subset.size
46
+ rbtree { 10000.times { rbtree[ select_subset[rand(size)] ] } }
47
+ splaytree { 10000.times { splaytree[ select_subset[rand(size)] ] } }
48
+ hash { 10000.times { hash[ select_subset[rand(size)] ] } }
49
+ end
50
+
51
+ end