ruby_algorithms 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 103e2764b69931bb01a62ccef977c353297cc1ce
4
+ data.tar.gz: cea9d0bc0e02ccd64de84980a12de3c7a5e2c2d5
5
+ SHA512:
6
+ metadata.gz: 1ad315eeb0965fcbcdc09a1a2720700e2858d9b966f2a3a6338c971b6d9ffae306786351bfedd2e3fa4edb996572bc1907fa0126d9e9f578ad133d50773996ea
7
+ data.tar.gz: 1991bf53b5967587292f27d6f0272322cc7fb9d25d29ff05d17c5a4ef39e6f102d1a069efa1d39a0546777e95ae81d0b47a242c29a29a36d1cfad7362255bc21
data/.byebug_history ADDED
@@ -0,0 +1,256 @@
1
+ quit
2
+ c
3
+ array[i]
4
+ c
5
+ counting_array
6
+ k
7
+ array[i]
8
+ c
9
+ counting_array
10
+ array[i]
11
+ c
12
+ array[i]
13
+ c
14
+ counting_array
15
+ array
16
+ array[i]
17
+ c
18
+ array[i]
19
+ counting_array
20
+ c
21
+ array[i]
22
+ counting_array
23
+ c
24
+ array[i]
25
+ counting_array
26
+ c
27
+ array[i]
28
+ counting_array
29
+ c
30
+ array[i]
31
+ c
32
+ b 89
33
+ counting_array
34
+ c
35
+ b 88
36
+ k
37
+ quit
38
+ array
39
+ c
40
+ array
41
+ c
42
+ array
43
+ c
44
+ array
45
+ c
46
+ array
47
+ c
48
+ array
49
+ c
50
+ array
51
+ c
52
+ array
53
+ c
54
+ array
55
+ c
56
+ array
57
+ c
58
+ array
59
+ c
60
+ array
61
+ c
62
+ array
63
+ c
64
+ array
65
+ c
66
+ array
67
+ c
68
+ largest
69
+ c
70
+ largest
71
+ array
72
+ c
73
+ largest
74
+ c
75
+ comparison
76
+ array
77
+ arrat
78
+ array[left]
79
+ array[left].send(comparison, array[i])
80
+ array[left].send(comparison, array[i]
81
+ largest
82
+ i
83
+ array
84
+ c
85
+ right
86
+ left
87
+ array[left]
88
+ array[left].send(comparison, array[i])
89
+ array[left].send(comparison, array[i]
90
+ array
91
+ c
92
+ largest
93
+ c
94
+ array
95
+ array[right]
96
+ array[right].send(comparison, array[largest])
97
+ array[right].send(comparison, array[largest]
98
+ array[left]
99
+ array[left].send(comparison, array[i])
100
+ array[i]
101
+ largest
102
+ left
103
+ i
104
+ array
105
+ c
106
+ largest
107
+ c
108
+ b 109
109
+ is_desc? ? :< : :>
110
+ is_desc?
111
+ is_desc
112
+ comparison
113
+ array[i]
114
+ array[left].send(comparison, array[i])
115
+ array[left]
116
+ 3 * 2 + 2
117
+ 3 * 2 + 1
118
+ 3 * 2
119
+ 8 / 2 - 1
120
+ 8 / 2
121
+ 4 * 2 + 1
122
+ 4 * 2
123
+ 2 * 2 + 1
124
+ array[2]
125
+ array.length/2 - 1
126
+ array.length/2
127
+ array.length
128
+ array
129
+ largest
130
+ quit
131
+ array
132
+ heapify array, 0, array.length
133
+ array[0] = 6
134
+ array
135
+ heapify array, 0, array.length
136
+ array
137
+ quit
138
+ test + array[0..2]
139
+ test = [1, 2, 3]
140
+ test
141
+ test.push(*array[1..2])
142
+ test.concat array[0..2]
143
+ test + array[0..2]
144
+ test << array[0..2]
145
+ test = []
146
+ test << array[0..2]
147
+ array[0..2]
148
+ left_array
149
+ array
150
+ j
151
+ left_array
152
+ c
153
+ i
154
+ left_array
155
+ r
156
+ p
157
+ c
158
+ right_array
159
+ k
160
+ r
161
+ p
162
+ c
163
+ left_array
164
+ r
165
+ p
166
+ k
167
+ quit
168
+ r
169
+ array2[j]
170
+ array1[i]
171
+ array[i]
172
+ k
173
+ r
174
+ p
175
+ c
176
+ b 52
177
+ array2
178
+ c
179
+ array2
180
+ array1
181
+ array[1]
182
+ q + j
183
+ j
184
+ r
185
+ n2
186
+ array
187
+ array1
188
+ array2
189
+ b 52
190
+ array1
191
+ left_array
192
+ b 50
193
+ p..r
194
+ j
195
+ q + j
196
+ j
197
+ left_array
198
+ c
199
+ b 46
200
+ p
201
+ i
202
+ c
203
+ b 42
204
+ n2
205
+ n1
206
+ r
207
+ q
208
+ p
209
+ n1
210
+ quit
211
+ 1..s
212
+ s = 5
213
+ n2 = r - m
214
+ n
215
+ n = m - p + 1
216
+ n = q - p + 1
217
+ r
218
+ p
219
+ m
220
+ quit
221
+ r
222
+ q
223
+ p
224
+ array
225
+ c
226
+ r
227
+ p
228
+ c
229
+ r
230
+ p
231
+ c
232
+ r
233
+ p
234
+ c
235
+ array
236
+ r
237
+ p
238
+ c
239
+ r
240
+ p
241
+ quit
242
+ r
243
+ p
244
+ c
245
+ r
246
+ p
247
+ c
248
+ q
249
+ c
250
+ b 29
251
+ quit
252
+ r
253
+ p
254
+ c
255
+ r
256
+ p
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ */.idea/
11
+ .idea/workspace.xml
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in algorithms.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 uchennafokoye
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Ruby Algorithms
2
+
3
+ This is currently in development. Feel free to send your feedback or comments to uchennafokoye@gmail.com.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'ruby_algorithms'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ruby_algorithms
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/lorem. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << "test"
7
+ t.libs << "test/sort_tests"
8
+ t.libs << "lib"
9
+ t.libs << "lib/ruby_algorithms/sort"
10
+ t.test_files = FileList['test/**/*_test.rb']
11
+ t.verbose = true
12
+ end
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="inheritedJdk" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ruby_algorithms"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/exe/algorithms ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ruby_algorithms'
@@ -0,0 +1,7 @@
1
+ module Interface
2
+ def method(name)
3
+ define_method(name) { |*args|
4
+ raise "interface method #{name} not implemented"
5
+ }
6
+ end
7
+ end
@@ -0,0 +1,87 @@
1
+ require 'sorting_interface'
2
+ class BubbleSort
3
+ # Important Characteristics
4
+ # 1. Compares all the elements one by one and sort them based on their values
5
+ # 2. Called bubble sort because each iteration the smaller element in the list bubles up towards the first place,
6
+ # just like a water bubble rises up to the water surface
7
+ # 3. In Bubble Sort, n-1 comparisons done in 1st pass, n-2 in 2nd pass
8
+ # Complexity:
9
+ # (n - 1) + (n - 2) + (n - 3) + ... 3 + 2 + 1
10
+ # Sum = n(n-1)/2
11
+ # i.e O(n^2)
12
+ # 4. Best case: O(n) when list is already sorted
13
+ #
14
+ # Example:
15
+ # array = [3, 2, 4, 5, 6, 1]
16
+ # array = BubbleSort.order(array)
17
+ # puts array # Output: [1, 2, 3, 4, 5, 6]
18
+ # Example:
19
+ # array = [3, 2, 4, 5, 6, 1]
20
+ # array = BubbleSort.order(array, :desc => true)
21
+ # puts array # Output: [6, 5, 4, 3, 2, 1]
22
+ #
23
+ # OR
24
+ #
25
+ # Example:
26
+ # array = [3, 2, 4, 5, 6, 1]
27
+ # bubble = BubbleSort.new(array)
28
+ # puts bubble.array # Output: [1, 2, 3, 4, 5, 6]
29
+ #
30
+ # Example:
31
+ # array = [3, 2, 4, 5, 6, 1]
32
+ # bubble = BubbleSort.new(array, :desc => true)
33
+ # puts bubble.array # Output: [6, 5, 4, 3, 2, 1]
34
+ #
35
+ #
36
+ # ### Get Time Complexity:
37
+ # Example:
38
+ # best = BubbleSort::TIME_COMPLEXITY_BEST
39
+ # worst = BubbleSort::TIME_COMPLEXITY_WORST
40
+ # average = BubbleSort::TIME_COMPLEXITY_AVERAGE
41
+
42
+ include SortingInterface
43
+ TIME_COMPLEXITY_WORST = "O(n^2)"
44
+ TIME_COMPLEXITY_AVERAGE = "O(n^2)"
45
+ TIME_COMPLEXITY_BEST = "O(n)"
46
+ attr_reader :array, :desc
47
+
48
+ def initialize array, desc=false
49
+ unless array.is_a? Enumerable
50
+ raise "Please provide an array or other Enumerable"
51
+ end
52
+ unless (array.all? {|item| item.is_a? Comparable})
53
+ raise "All objects must implement Comparable"
54
+ end
55
+ @array = array
56
+ @desc = desc
57
+ self.sort
58
+ end
59
+
60
+ def self.order array, desc=false
61
+ instance = BubbleSort.new array, desc=desc
62
+ instance.array
63
+ end
64
+
65
+ protected
66
+ def sort
67
+ bubble_sort
68
+ end
69
+
70
+ def is_desc?
71
+ @desc
72
+ end
73
+
74
+ def bubble_sort
75
+ array = @array
76
+ for i in 1...array.length
77
+ (array.length-1).downto i do |j|
78
+ comparison = (is_desc?) ? array[j] > array[j-1] : array[j] < array[j-1]
79
+ if comparison
80
+ swap array, j, j-1
81
+ end
82
+ end
83
+
84
+ end
85
+ end
86
+
87
+ end
@@ -0,0 +1,99 @@
1
+ require 'sorting_interface'
2
+ class CountingSort
3
+ # Important Characteristics
4
+ # 1. Must have values between (0, k) where k is larger than every value in the array
5
+ # 2. Counting sort is extremely fast -- Theta(k + n), O(n) for worst case, best case and average
6
+ # 3. Uses spaces O(k + n)
7
+ # 4. Uses spaces O(k + n)
8
+ # Example:
9
+ # array = [3, 2, 4, 5, 6, 1]
10
+ # array = CountingSort.order(array)
11
+ # puts array # Output: [1, 2, 3, 4, 5, 6]
12
+ # Example:
13
+ # array = [3, 2, 4, 5, 6, 1]
14
+ # array = CountingSort.order(array, :desc => true)
15
+ # puts array # Output: [6, 5, 4, 3, 2, 1]
16
+ #
17
+ # OR
18
+ #
19
+ # Example:
20
+ # array = [3, 2, 4, 5, 6, 1]
21
+ # instance = CountingSort.new(array)
22
+ # puts instance.array # Output: [1, 2, 3, 4, 5, 6]
23
+ #
24
+ # Example:
25
+ # array = [3, 2, 4, 5, 6, 1]
26
+ # instance = CountingSort.new(array, :desc => true)
27
+ # puts instance.array # Output: [6, 5, 4, 3, 2, 1]
28
+ #
29
+ #
30
+ # ### Get Time Complexity:
31
+ # Example:
32
+ # best = CountingSort::TIME_COMPLEXITY_BEST
33
+ # worst = CountingSort::TIME_COMPLEXITY_WORST
34
+ # average = CountingSort::TIME_COMPLEXITY_AVERAGE
35
+
36
+ include SortingInterface
37
+
38
+ TIME_COMPLEXITY_WORST = "O(n)"
39
+ TIME_COMPLEXITY_AVERAGE = "O(n)"
40
+ TIME_COMPLEXITY_BEST = "O(n)"
41
+ SPACE_COMPLEXITY = "O(k+n)"
42
+
43
+ attr_reader :array, :desc, :k
44
+
45
+ # For more on k variable, read on counting sort
46
+ # k indicates that every number in the container is in the range (0, k)
47
+ def initialize array, k, desc=false
48
+ unless array.is_a? Enumerable
49
+ raise "Please provide an array or other Enumerable"
50
+ end
51
+ unless (array.all? {|item| item.is_a? Comparable})
52
+ raise "All objects must implement Comparable"
53
+ end
54
+ unless (array.all? {|item| item >= 0 && item < k})
55
+ raise "All items in array must be greater than or equal to 0 and less than k"
56
+ end
57
+ @array = array
58
+ @desc = desc
59
+ @k = k
60
+ self.sort
61
+ end
62
+
63
+ def self.order array, k, desc=false
64
+ instance = CountingSort.new array, k, desc=desc
65
+ instance.array
66
+ end
67
+
68
+ protected
69
+ def sort
70
+ n = array.length
71
+ counting_sort array, k
72
+ end
73
+
74
+ def is_desc?
75
+ @desc
76
+ end
77
+
78
+ def counting_sort array, k
79
+ n = array.length
80
+ counting_array = Array.new k, 0
81
+ for i in 0...n
82
+ counting_array[array[i]] += 1
83
+ end
84
+
85
+ idx = 0
86
+ comparison = is_desc? ? ((k-1).downto 0) : 0...k
87
+ for i in comparison
88
+ while counting_array[i] > 0
89
+ array[idx] = i
90
+ counting_array[i] -= 1
91
+ idx += 1
92
+ end
93
+ end
94
+
95
+
96
+ end
97
+
98
+
99
+ end
@@ -0,0 +1,116 @@
1
+ require 'sorting_interface'
2
+ class HeapSort
3
+ # Important Characteristics
4
+ # 1. One of the best sorting methods being in-place and with no quadratic worst-case scenarios
5
+ # 2. Involves two basic parts:
6
+ # - Creating a Heap of the unsorted list
7
+ # - Then a sorted array is created by repeatedly removing the largest/smallest element
8
+ # from the heap and inserting it into the array. The heap is reconstructed after each removal.
9
+ # Example:
10
+ # array = [3, 2, 4, 5, 6, 1]
11
+ # array = HeapSort.order(array)
12
+ # puts array # Output: [1, 2, 3, 4, 5, 6]
13
+ # Example:
14
+ # array = [3, 2, 4, 5, 6, 1]
15
+ # array = HeapSort.order(array, :desc => true)
16
+ # puts array # Output: [6, 5, 4, 3, 2, 1]
17
+ #
18
+ # OR
19
+ #
20
+ # Example:
21
+ # array = [3, 2, 4, 5, 6, 1]
22
+ # heap_sort = HeapSort.new(array)
23
+ # puts heap.array # Output: [1, 2, 3, 4, 5, 6]
24
+ #
25
+ # Example:
26
+ # array = [3, 2, 4, 5, 6, 1]
27
+ # insertion = HeapSort.new(array, :desc => true)
28
+ # puts insertion.array # Output: [6, 5, 4, 3, 2, 1]
29
+ #
30
+ #
31
+ # ### Get Time Complexity:
32
+ # Example:
33
+ # best = HeapSort::TIME_COMPLEXITY_BEST
34
+ # worst = HeapSort::TIME_COMPLEXITY_WORST
35
+ # average = HeapSort::TIME_COMPLEXITY_AVERAGE
36
+
37
+ include SortingInterface
38
+
39
+ TIME_COMPLEXITY_WORST = "O(n log n)"
40
+ TIME_COMPLEXITY_AVERAGE = "O(n log n)"
41
+ TIME_COMPLEXITY_BEST = "O(n log n)"
42
+ SPACE_COMPLEXITY = "O(n)"
43
+
44
+ attr_reader :array, :desc
45
+
46
+ def initialize array, desc=false
47
+ unless array.is_a? Enumerable
48
+ raise "Please provide an array or other Enumerable"
49
+ end
50
+ unless (array.all? {|item| item.is_a? Comparable})
51
+ raise "All objects must implement Comparable"
52
+ end
53
+ @array = array
54
+ @desc = desc
55
+ self.sort
56
+ end
57
+
58
+ def self.order array, desc=false
59
+ instance = HeapSort.new array, desc=desc
60
+ instance.array
61
+ end
62
+
63
+ protected
64
+ def sort
65
+ heap_sort array
66
+ end
67
+
68
+ def is_desc?
69
+ @desc
70
+ end
71
+
72
+ def comparison
73
+ # contrary to what may be expected:
74
+ # - create min-heap for descending sort i.e. 9 8 7 6 5 4
75
+ # - create max-heap for ascending sort i.e. 4 5 6 7 8 9
76
+ is_desc? ? :< : :>
77
+ end
78
+
79
+ def heap_sort array
80
+ build_heap(array)
81
+ n = array.length - 1
82
+ for heapsize in n.downto 1
83
+ swap array, 0, heapsize
84
+ heapify array, 0, heapsize
85
+ end
86
+
87
+ end
88
+
89
+ def build_heap array
90
+ n = array.length
91
+ half = (n/2).floor - 1
92
+ for i in half.downto 0
93
+ heapify array, i, n
94
+ end
95
+ end
96
+
97
+ def heapify array, i, heapsize
98
+ left = 2 * i + 1
99
+ right = 2 * i + 2
100
+
101
+ largest = i
102
+
103
+ if (left < heapsize && array[left].send(comparison, array[i]))
104
+ largest = left
105
+ end
106
+
107
+ if (right < heapsize && array[right].send(comparison, array[largest]))
108
+ largest = right
109
+ end
110
+ if largest != i
111
+ swap array, i, largest
112
+ heapify(array, largest, heapsize)
113
+ end
114
+ end
115
+
116
+ end
@@ -0,0 +1,92 @@
1
+ class InsertionSort
2
+
3
+ # Important Characteristics
4
+ # 1. It has one of the simplest implementations
5
+ # 2. It is efficient for smaller data sets, but very inefficient for larger list
6
+ # 3. Insertion Sort is adaptive, that means it reduces its total number of steps if given a partially sorted list, hence it increases its efficiency
7
+ # 4. It is better than Selection Sort and Bubble Sort algorithms
8
+ # 5. Its space complexity is less; Like Buble Sort, insertion sort also requires a single additional memory space
9
+ # 6. It is Stable, as it does not change the relative order of elements with equal keys
10
+ #
11
+ # Example:
12
+ # array = [3, 2, 4, 5, 6, 1]
13
+ # array = InsertionSort.order(array)
14
+ # puts array # Output: [1, 2, 3, 4, 5, 6]
15
+ # Example:
16
+ # array = [3, 2, 4, 5, 6, 1]
17
+ # array = InsertionSort.order(array, :desc => true)
18
+ # puts array # Output: [6, 5, 4, 3, 2, 1]
19
+ #
20
+ # OR
21
+ #
22
+ # Example:
23
+ # array = [3, 2, 4, 5, 6, 1]
24
+ # insertion = InsertionSort.new(array)
25
+ # puts insertion.array # Output: [1, 2, 3, 4, 5, 6]
26
+ #
27
+ # Example:
28
+ # array = [3, 2, 4, 5, 6, 1]
29
+ # insertion = InsertionSort.new(array, :desc => true)
30
+ # puts insertion.array # Output: [6, 5, 4, 3, 2, 1]
31
+ #
32
+ #
33
+ # ### Get Time Complexity:
34
+ # Example:
35
+ # best = InsertionSort::TIME_COMPLEXITY_BEST
36
+ # worst = InsertionSort::TIME_COMPLEXITY_WORST
37
+ # average = InsertionSort::TIME_COMPLEXITY_AVERAGE
38
+
39
+
40
+ TIME_COMPLEXITY_WORST = "O(n^2)"
41
+ TIME_COMPLEXITY_AVERAGE = "O(n^2)"
42
+ TIME_COMPLEXITY_BEST = "O(n)"
43
+ attr_reader :array, :desc
44
+
45
+ def initialize array, desc=false
46
+ unless array.is_a? Enumerable
47
+ raise "Please provide an array or other Enumerable"
48
+ end
49
+ unless (array.all? {|item| item.is_a? Comparable})
50
+ raise "All objects must implement Comparable"
51
+ end
52
+ @array = array
53
+ @desc = desc
54
+ self.sort
55
+ end
56
+
57
+ def self.order array, desc=false
58
+ instance = InsertionSort.new array, desc=desc
59
+ instance.array
60
+ end
61
+
62
+ protected
63
+ def sort
64
+ insertion_sort
65
+ end
66
+
67
+ def is_desc?
68
+ @desc
69
+ end
70
+
71
+ # You carry a pointer. This pointer indicates last sorted point
72
+ # You iterate backwards comparing new pointer (i) to all other array points (j)
73
+ # If it is less than/greater than, then place it in its rightful position
74
+ # For descending order, just do the opposite.
75
+ def insertion_sort
76
+ array = @array
77
+ for i in 1...array.length
78
+ current_no = array[i]
79
+ j = i - 1
80
+ while j >= 0
81
+ comparison = is_desc? ? (current_no > array[j]) : (current_no < array[j])
82
+ unless comparison
83
+ break
84
+ end
85
+ array[j+1] = array[j]
86
+ j = j - 1
87
+ end
88
+ array[j+1] = current_no
89
+ end
90
+ end
91
+
92
+ end
@@ -0,0 +1,122 @@
1
+ class MergeSort
2
+
3
+ # Important Characteristics
4
+ # 1. It is quite fast and has a time complexity of O(n log n)
5
+ # 2. Time complexity of Merge Sort is O (n log n) in all 3 cases (worst, average and best)
6
+ # as merge sort always divides the array in two halves and takes linear time to merge two halves
7
+ # 3. It requires equal amount of additional space as the unsorted lsit. Hence its not at all recommended for search large unsorted lists
8
+ # 4. It is the best Sorting technique for sorting Linked lists
9
+ # 5. It follows the rule of Divide and Conquer
10
+ # 6. It is Stable, as it does not change the relative order of elements with equal keys
11
+ # Example:
12
+ # array = [3, 2, 4, 5, 6, 1]
13
+ # array = MergeSort.order(array)
14
+ # puts array # Output: [1, 2, 3, 4, 5, 6]
15
+ # Example:
16
+ # array = [3, 2, 4, 5, 6, 1]
17
+ # array = MergeSort.order(array, :desc => true)
18
+ # puts array # Output: [6, 5, 4, 3, 2, 1]
19
+ #
20
+ # OR
21
+ #
22
+ # Example:
23
+ # array = [3, 2, 4, 5, 6, 1]
24
+ # insertion = MergeSort.new(array)
25
+ # puts insertion.array # Output: [1, 2, 3, 4, 5, 6]
26
+ #
27
+ # Example:
28
+ # array = [3, 2, 4, 5, 6, 1]
29
+ # insertion = MergeSort.new(array, :desc => true)
30
+ # puts insertion.array # Output: [6, 5, 4, 3, 2, 1]
31
+ #
32
+ #
33
+ # ### Get Time Complexity:
34
+ # Example:
35
+ # best = MergeSort::TIME_COMPLEXITY_BEST
36
+ # worst = MergeSort::TIME_COMPLEXITY_WORST
37
+ # average = MergeSort::TIME_COMPLEXITY_AVERAGE
38
+ # space = MergeSort::SPACE_COMPLEXITY
39
+
40
+ TIME_COMPLEXITY_WORST = "O(n log(n))"
41
+ TIME_COMPLEXITY_AVERAGE = "O(n log(n))"
42
+ TIME_COMPLEXITY_BEST = "O(n log(n))"
43
+ SPACE_COMPLEXITY = "O(n)"
44
+
45
+ attr_reader :array, :desc
46
+ def initialize array, desc=false
47
+ unless array.is_a? Enumerable
48
+ raise "Please provide an array or other Enumerable"
49
+ end
50
+ unless (array.all? {|item| item.is_a? Comparable})
51
+ raise "All objects must implement Comparable"
52
+ end
53
+ @array = array
54
+ @desc = desc
55
+ self.sort
56
+ end
57
+
58
+ def self.order array, desc=false
59
+ instance = MergeSort.new array, desc=desc
60
+ instance.array
61
+ end
62
+
63
+ protected
64
+ def sort
65
+ merge_sort @array, 0, array.length - 1
66
+ end
67
+
68
+ def merge_sort array, p, r
69
+ if p < r
70
+ q = ((p + r) / 2).floor
71
+ merge_sort(array, p, q)
72
+ merge_sort(array, q + 1, r)
73
+ merge(array, p, q, r)
74
+ end
75
+ end
76
+
77
+ def merge array, p, q, r
78
+ n1 = q - p + 1
79
+ n2 = r - q
80
+ left_array = []
81
+ right_array = []
82
+
83
+ for i in 1..n1
84
+ left_array[i] = array[p + i - 1]
85
+ end
86
+
87
+ for j in 1..n2
88
+ right_array[j] = array[q + j]
89
+ end
90
+
91
+ i = 1
92
+ j = 1
93
+ for k in p..r
94
+
95
+ if i >= left_array.length && (j < right_array.length)
96
+ array[k] = right_array[j]
97
+ j = j + 1
98
+ next
99
+ elsif j >= right_array.length && (i < left_array.length)
100
+ array[k] = left_array[i]
101
+ i = i + 1
102
+ next
103
+ elsif j >= right_array.length && i >= left_array.length
104
+ break
105
+ end
106
+
107
+ comparison = is_desc? ? (left_array[i] >= right_array[j]) : (left_array[i] <= right_array[j])
108
+ if comparison
109
+ array[k] = left_array[i]
110
+ i = i + 1
111
+ else
112
+ array[k] = right_array[j]
113
+ j = j + 1
114
+ end
115
+ end
116
+ end
117
+
118
+ def is_desc?
119
+ @desc
120
+ end
121
+
122
+ end
@@ -0,0 +1,107 @@
1
+ require 'sorting_interface'
2
+ class QuickSort
3
+ # Important Characteristics
4
+ # 1. Worst case is O(n ^ 2) but typically runs O (n log n)
5
+ # 2. Not stable sort so it might change the occurence of two similar elements
6
+ # in the list while sorting
7
+ # 3. Can be very fast and requires very less additional space
8
+ # 4. The algorithm divides the list into three main parts:
9
+ # - Elements less than the Pivot element
10
+ # - Pivot element
11
+ # - Elements greater than the pivot element
12
+ # 5. Techniques Used:
13
+ # - Divide and conquer
14
+ # - Recursion
15
+ # - Array
16
+ # Example:
17
+ # array = [3, 2, 4, 5, 6, 1]
18
+ # array = QuickSort.order(array)
19
+ # puts array # Output: [1, 2, 3, 4, 5, 6]
20
+ # Example:
21
+ # array = [3, 2, 4, 5, 6, 1]
22
+ # array = QuickSort.order(array, :desc => true)
23
+ # puts array # Output: [6, 5, 4, 3, 2, 1]
24
+ #
25
+ # OR
26
+ #
27
+ # Example:
28
+ # array = [3, 2, 4, 5, 6, 1]
29
+ # instance = QuickSort.new(array)
30
+ # puts instance.array # Output: [1, 2, 3, 4, 5, 6]
31
+ #
32
+ # Example:
33
+ # array = [3, 2, 4, 5, 6, 1]
34
+ # instance = QuickSort.new(array, :desc => true)
35
+ # puts instance.array # Output: [6, 5, 4, 3, 2, 1]
36
+ #
37
+ #
38
+ # ### Get Time Complexity:
39
+ # Example:
40
+ # best = QuickSort::TIME_COMPLEXITY_BEST
41
+ # worst = QuickSort::TIME_COMPLEXITY_WORST
42
+ # average = QuickSort::TIME_COMPLEXITY_AVERAGE
43
+
44
+ include SortingInterface
45
+
46
+ TIME_COMPLEXITY_WORST = "O(n^2)"
47
+ TIME_COMPLEXITY_AVERAGE = "O(n log n)"
48
+ TIME_COMPLEXITY_BEST = "O(n log n)"
49
+ SPACE_COMPLEXITY = "O(n log n)"
50
+
51
+ attr_reader :array, :desc
52
+
53
+ def initialize array, desc=false
54
+ unless array.is_a? Enumerable
55
+ raise "Please provide an array or other Enumerable"
56
+ end
57
+ unless (array.all? {|item| item.is_a? Comparable})
58
+ raise "All objects must implement Comparable"
59
+ end
60
+ @array = array
61
+ @desc = desc
62
+ self.sort
63
+ end
64
+
65
+ def self.order array, desc=false
66
+ instance = QuickSort.new array, desc=desc
67
+ instance.array
68
+ end
69
+
70
+ protected
71
+ def sort
72
+ n = array.length
73
+ quick_sort array, 0, n - 1
74
+ end
75
+
76
+ def is_desc?
77
+ @desc
78
+ end
79
+
80
+ def comparison_symbol
81
+ is_desc? ? :>= : :<=
82
+ end
83
+
84
+ def quick_sort array, left, right
85
+
86
+ if left < right
87
+ pi = partition array, left, right
88
+ quick_sort array, left, pi - 1
89
+ quick_sort array, pi + 1, right
90
+ end
91
+
92
+ end
93
+
94
+ def partition array, left, right
95
+ pivot = ((left + right) / 2).floor # could be randomly chosen but chose middle
96
+ swap array, pivot, right
97
+ store = left
98
+ for i in left..right-1
99
+ if array[i].send(comparison_symbol, array[right])
100
+ swap array, store, i
101
+ store = store + 1
102
+ end
103
+ end
104
+ swap array, store, right
105
+ return store
106
+ end
107
+ end
@@ -0,0 +1,37 @@
1
+ require 'insertion_sort'
2
+ require 'merge_sort'
3
+ require 'bubble_sort'
4
+ class Sortable
5
+ attr_reader :array, :desc
6
+ def initialize array, desc=false
7
+ unless array.is_a? Enumerable
8
+ raise "Please provide an array or other Enumerable"
9
+ end
10
+ unless (array.all? {|item| item.is_a? Comparable})
11
+ raise "All objects must implement Comparable"
12
+ end
13
+ @array = array
14
+ @desc = desc
15
+ end
16
+
17
+ def insertion_sort!
18
+ @array = InsertionSort.order(@array, desc=@desc)
19
+ end
20
+
21
+ def merge_sort!
22
+ @array = MergeSort.order(@array, desc= @desc)
23
+ end
24
+
25
+ def equal? sortable
26
+ unless sortable.is_a? Sortable
27
+ return false
28
+ end
29
+ self.array == sortable.array
30
+ end
31
+
32
+ protected
33
+ def is_desc?
34
+ @desc
35
+ end
36
+
37
+ end
@@ -0,0 +1,5 @@
1
+ module SortingInterface
2
+ def swap array, i, j
3
+ array[i], array[j] = array[j], array[i]
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ require 'helpers/interface'
2
+ require 'ruby_algorithms/sort/sortable'
3
+ class Sort
4
+ def initialize
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ module RubyAlgorithms
2
+ VERSION = "0.0.1.pre"
3
+ NAME = "ruby_algorithms"
4
+ SUMMARY = 'This gem includes the common data structures and algorithms.'
5
+ DESCRIPTION = 'This gem includes the common data structures and algorithms.'
6
+ AUTHORS = ['Uchenna F. Okoye']
7
+ DATE = '2016-03-30'
8
+ LICENSE = 'MIT'
9
+ HOMEPAGE = 'https://github.com/ruby-math/RubyAlgorithms'
10
+ EMAIL = 'uchennafokoye@gmail.com'
11
+ end
@@ -0,0 +1,4 @@
1
+ module RubyAlgorithms
2
+ end
3
+ require 'ruby_algorithms/sort'
4
+
@@ -0,0 +1,38 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'ruby_algorithms/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = RubyAlgorithms::NAME
7
+ s.version = RubyAlgorithms::VERSION
8
+ s.date = RubyAlgorithms::DATE
9
+ s.summary = RubyAlgorithms::SUMMARY
10
+ s.description = RubyAlgorithms::DESCRIPTION
11
+ s.authors = RubyAlgorithms::AUTHORS
12
+ s.email = RubyAlgorithms::EMAIL
13
+ s.homepage = RubyAlgorithms::HOMEPAGE
14
+ s.license = RubyAlgorithms::LICENSE
15
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
16
+ # delete this section to allow pushing this gem to any host.
17
+ if s.respond_to?(:metadata)
18
+ s.metadata['allowed_push_host'] = 'https://rubygems.org'
19
+ else
20
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
21
+ end
22
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|s|features)/}) }
23
+ s.bindir = "exe"
24
+ s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ s.require_paths = ["lib", "lib/ruby_algorithms", "lib/ruby_algorithms/sort"]
26
+
27
+ s.add_development_dependency "bundler", "~> 1.10"
28
+ s.add_development_dependency "rake", "~> 10.0"
29
+ s.add_development_dependency "rdoc"
30
+ s.add_development_dependency "minitest"
31
+ s.add_development_dependency "minitest-reporters"
32
+ s.add_development_dependency "simplecov"
33
+ s.add_development_dependency "byebug"
34
+ s.add_development_dependency "pry"
35
+ s.add_development_dependency "pry-rescue"
36
+
37
+
38
+ end
metadata ADDED
@@ -0,0 +1,197 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_algorithms
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.pre
5
+ platform: ruby
6
+ authors:
7
+ - Uchenna F. Okoye
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-03-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rdoc
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-reporters
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: byebug
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry-rescue
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: This gem includes the common data structures and algorithms.
140
+ email: uchennafokoye@gmail.com
141
+ executables:
142
+ - algorithms
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".byebug_history"
147
+ - ".gitignore"
148
+ - CODE_OF_CONDUCT.md
149
+ - Gemfile
150
+ - LICENSE.txt
151
+ - README.md
152
+ - Rakefile
153
+ - algorithms/.idea/data_structures_and_algorithms.iml
154
+ - bin/console
155
+ - bin/setup
156
+ - exe/algorithms
157
+ - lib/helpers/interface.rb
158
+ - lib/ruby_algorithms.rb
159
+ - lib/ruby_algorithms/sort.rb
160
+ - lib/ruby_algorithms/sort/bubble_sort.rb
161
+ - lib/ruby_algorithms/sort/counting_sort.rb
162
+ - lib/ruby_algorithms/sort/heap_sort.rb
163
+ - lib/ruby_algorithms/sort/insertion_sort.rb
164
+ - lib/ruby_algorithms/sort/merge_sort.rb
165
+ - lib/ruby_algorithms/sort/quick_sort.rb
166
+ - lib/ruby_algorithms/sort/sortable.rb
167
+ - lib/ruby_algorithms/sort/sorting_interface.rb
168
+ - lib/ruby_algorithms/version.rb
169
+ - ruby_algorithms.gemspec
170
+ homepage: https://github.com/ruby-math/RubyAlgorithms
171
+ licenses:
172
+ - MIT
173
+ metadata:
174
+ allowed_push_host: https://rubygems.org
175
+ post_install_message:
176
+ rdoc_options: []
177
+ require_paths:
178
+ - lib
179
+ - lib/ruby_algorithms
180
+ - lib/ruby_algorithms/sort
181
+ required_ruby_version: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ required_rubygems_version: !ruby/object:Gem::Requirement
187
+ requirements:
188
+ - - ">"
189
+ - !ruby/object:Gem::Version
190
+ version: 1.3.1
191
+ requirements: []
192
+ rubyforge_project:
193
+ rubygems_version: 2.4.5.1
194
+ signing_key:
195
+ specification_version: 4
196
+ summary: This gem includes the common data structures and algorithms.
197
+ test_files: []