algorithm_selector 0.1.0

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.
@@ -0,0 +1,114 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ Top Level Namespace
8
+
9
+ &mdash; Documentation by YARD 0.9.4
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ pathId = "";
19
+ relpath = '';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="class_list.html"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="_index.html">Index</a> &raquo;
40
+
41
+
42
+ <span class="title">Top Level Namespace</span>
43
+
44
+ </div>
45
+
46
+ <div id="search">
47
+
48
+ <a class="full_list_link" id="class_list_link"
49
+ href="class_list.html">
50
+
51
+ <svg width="24" height="24">
52
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
+ </svg>
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <iframe id="search_frame" src="class_list.html"></iframe>
63
+
64
+ <div id="content"><h1>Top Level Namespace
65
+
66
+
67
+
68
+ </h1>
69
+ <div class="box_info">
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+
80
+
81
+ </div>
82
+
83
+ <h2>Defined Under Namespace</h2>
84
+ <p class="children">
85
+
86
+
87
+ <strong class="modules">Modules:</strong> <span class='object_link'><a href="AlgorithmSelector.html" title="AlgorithmSelector (module)">AlgorithmSelector</a></span>
88
+
89
+
90
+
91
+ <strong class="classes">Classes:</strong> <span class='object_link'><a href="BSTNode.html" title="BSTNode (class)">BSTNode</a></span>, <span class='object_link'><a href="BinaryTree.html" title="BinaryTree (class)">BinaryTree</a></span>, <span class='object_link'><a href="LinkNode.html" title="LinkNode (class)">LinkNode</a></span>, <span class='object_link'><a href="LinkedList.html" title="LinkedList (class)">LinkedList</a></span>, <span class='object_link'><a href="Queue.html" title="Queue (class)">Queue</a></span>, <span class='object_link'><a href="Searches.html" title="Searches (class)">Searches</a></span>, <span class='object_link'><a href="Sorts.html" title="Sorts (class)">Sorts</a></span>, <span class='object_link'><a href="Stack.html" title="Stack (class)">Stack</a></span>
92
+
93
+
94
+ </p>
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+
104
+ </div>
105
+
106
+ <div id="footer">
107
+ Generated on Fri Jul 22 11:22:30 2016 by
108
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
109
+ 0.9.4 (ruby-2.1.2).
110
+ </div>
111
+
112
+ </div>
113
+ </body>
114
+ </html>
Binary file
@@ -0,0 +1,562 @@
1
+ require "algorithm_selector/version"
2
+
3
+ module AlgorithmSelector
4
+ extend self
5
+
6
+ # get all algorithms
7
+ def all(type, array, num_tests=1, target=nil)
8
+ if type == "sort"
9
+ Sorts.new.all(array, num_tests)
10
+ elsif type == "search"
11
+ Searches.new.all(array, num_tests, target)
12
+ end
13
+ end
14
+
15
+ # get best algorithm
16
+ def best(type, array, num_tests=1, target=nil)
17
+ if type == "sort"
18
+ Sorts.new.best(array, num_tests)
19
+ elsif type == "search"
20
+ Searches.new.best(array, num_tests, target)
21
+ end
22
+ end
23
+
24
+ # get one algorithm by name
25
+ def analyze(type, array, algorithm_name, num_tests=1, target=nil)
26
+ if type == "sort"
27
+ Sorts.new.analyze(array, algorithm_name, num_tests)
28
+ elsif type == "search"
29
+ Searches.new.analyze(array, algorithm_name, num_tests, target)
30
+ end
31
+ end
32
+
33
+ # compare two algorithms
34
+ def compare(type, array, first_algorithm_name, second_algorithm_name, num_tests=1, target=nil)
35
+ if type == "sort"
36
+ Sorts.new.compare(array, first_algorithm_name, second_algorithm_name, num_tests)
37
+ elsif type == "search"
38
+ Searches.new.compare(array, first_algorithm_name, second_algorithm_name, num_tests, target)
39
+ end
40
+ end
41
+
42
+ # call sort algorithm method
43
+ def sort(array, algorithm_name)
44
+ method = Sorts.new.method(algorithm_name)
45
+ method.call(array)
46
+ end
47
+
48
+ end
49
+
50
+ # Sorts class
51
+ class Sorts
52
+ # Show all results from sorting algorithms
53
+ def all(array, num_tests)
54
+ {
55
+ sorted: merge_sort(array),
56
+ results: {
57
+ bubble_sort: display_time(Proc.new {bubble_sort(array)}, num_tests),
58
+ insertion_sort: display_time(Proc.new {insertion_sort(array)}, num_tests),
59
+ selection_sort: display_time(Proc.new {selection_sort(array)}, num_tests),
60
+ merge_sort: display_time(Proc.new {merge_sort(array)}, num_tests),
61
+ quick_sort: display_time(Proc.new {quick_sort(array)}, num_tests)
62
+ }
63
+ }
64
+ end
65
+
66
+ # Show the best sorting algorithm
67
+ def best(array, num_tests)
68
+ hash = all(array, num_tests)
69
+ best_time = 0
70
+ best_algorithm = {}
71
+ hash[:results].each do |key, val|
72
+ if val < best_time || best_time == 0
73
+ best_time = val
74
+ best_algorithm = Hash[key, val]
75
+ end
76
+ end
77
+ {
78
+ best_algorithm.keys[0] => best_algorithm[best_algorithm.keys[0]]
79
+ }
80
+ end
81
+
82
+ # Analyze specific sorting algorithm by name
83
+ def analyze(array, algorithm, num_tests)
84
+ hash = all(array, num_tests)
85
+ alg = {}
86
+ hash[:results].each do |key, val|
87
+ if algorithm.to_sym == key
88
+ alg = Hash[key, val]
89
+ end
90
+ end
91
+ {
92
+ sorted: hash[:sorted],
93
+ alg.keys[0] => alg[alg.keys[0]]
94
+ }
95
+ end
96
+
97
+ # Compare two algorithms for data set
98
+ def compare(array, first_algorithm, second_algorithm, num_tests)
99
+ hash = all(array, num_tests)
100
+ first = {}
101
+ second = {}
102
+ hash[:results].each do |key, val|
103
+ if first_algorithm.to_sym == key
104
+ first = Hash[key, val]
105
+ elsif second_algorithm.to_sym == key
106
+ second = Hash[key, val]
107
+ end
108
+ end
109
+ {
110
+ first.keys[0] => first[first.keys[0]],
111
+ second.keys[0] => second[second.keys[0]]
112
+ }
113
+ end
114
+
115
+ # Bubble sort
116
+ # Worst-Case Space Complexity: O(1)
117
+ # Averge-Case Time Complexity: O(n^2)
118
+ # Worst-Case Time Complexity: O(n^2)
119
+ def bubble_sort(array)
120
+ return array if array.length < 2
121
+ switched = true
122
+ until switched == false
123
+ switched = false
124
+ (1...array.length).each do |i|
125
+ if array[i-1] > array[i]
126
+ temp = array[i]
127
+ array[i] = array[i-1]
128
+ array[i-1] = temp
129
+ switched = true
130
+ end
131
+ end
132
+ end
133
+ return array
134
+ end
135
+
136
+ # Insertion sort
137
+ # Worst-Case Space Complexity: O(1)
138
+ # Averge-Case Time Complexity: O(n^2)
139
+ # Worst-Case Time Complexity: O(n^2)
140
+ def insertion_sort(array)
141
+ return array if array.length < 2
142
+ (1...array.length).to_a do |i|
143
+ value = array[i]
144
+ j = i - 1
145
+ while (j >= 0 && array[j] > value) do
146
+ array[j+1] = array[j]
147
+ j = j - 1
148
+ end
149
+ array[j+1] = value
150
+ end
151
+ array
152
+ end
153
+
154
+ # Selection sort
155
+ # Worst-Case Space Complexity: O(1)
156
+ # Averge-Case Time Complexity: O(n^2)
157
+ # Worst-Case Time Complexity: O(n^2)
158
+ def selection_sort(array)
159
+ (0...array.length-1).to_a.each do |i|
160
+ min = i
161
+ (i+1...array.length).to_a.each do |j|
162
+ if (array[j] < array[min])
163
+ min = j
164
+ end
165
+ end
166
+ if min != i
167
+ array[min], array[i] = array[i], array[min]
168
+ end
169
+ end
170
+ return array
171
+ end
172
+
173
+ # Merge sort
174
+ # Worst-Case Space Complexity: O(n)
175
+ # Averge-Case Time Complexity: O(n log(n))
176
+ # Worst-Case Time Complexity: O(n log(n))
177
+ def merge_sort(array)
178
+ return array if array.length < 2
179
+ middle = array.length/2
180
+ left = array[0...middle]
181
+ right = array[middle...array.length]
182
+ merge(merge_sort(left), merge_sort(right))
183
+ end
184
+
185
+ # Quick sort
186
+ # Worst-Case Space Complexity: O(log(n))
187
+ # Averge-Case Time Complexity: O(n log(n))
188
+ # Worst-Case Time Complexity: O(n^2)
189
+ def quick_sort(array)
190
+ return array if array.count < 2
191
+ pivot = array[0]
192
+ left = array.select {|el| el < pivot}
193
+ right = array.select {|el| el > pivot}
194
+ quick_sort(left) + [pivot] + quick_sort(right)
195
+ end
196
+ end
197
+
198
+ class Searches
199
+ def all(array, num_tests, target)
200
+ stack = Stack.new(array.length, array)
201
+ queue = Queue.new(array.length, array)
202
+ linked_list = LinkedList.new(array)
203
+ binary_tree = BinaryTree.new(array)
204
+ {
205
+ found: stack.search(target),
206
+ results:
207
+ {
208
+ stack: display_time(Proc.new {stack.search(target)}, num_tests),
209
+ queue: display_time(Proc.new {queue.search(target)}, num_tests),
210
+ linked_list: display_time(Proc.new {linked_list.search(target)}, num_tests),
211
+ binary_tree: display_time(Proc.new {binary_tree.search(target)}, num_tests)
212
+ }
213
+ }
214
+ end
215
+
216
+ def best(array, num_tests, target)
217
+ hash = all(array, num_tests, target)
218
+ best_time = 0
219
+ best_algorithm = {}
220
+ hash[:results].each do |key, val|
221
+ if val < best_time || best_time == 0
222
+ best_time = val
223
+ best_algorithm = Hash[key, val]
224
+ end
225
+ end
226
+ {
227
+ best_algorithm.keys[0] => best_algorithm[best_algorithm.keys[0]]
228
+ }
229
+ end
230
+
231
+ def analyze(array, algorithm, num_tests, target)
232
+ hash = all(array, num_tests, target)
233
+ alg = {}
234
+ hash[:results].each do |key, val|
235
+ if algorithm.to_sym == key
236
+ alg = Hash[key, val]
237
+ end
238
+ end
239
+ {
240
+ found: hash[:found],
241
+ alg.keys[0] => alg[alg.keys[0]]
242
+ }
243
+ end
244
+
245
+ def compare(array, first_algorithm, second_algorithm, num_tests, target)
246
+ hash = all(array, num_tests, target)
247
+ first = {}
248
+ second = {}
249
+ hash[:results].each do |key, val|
250
+ if first_algorithm.to_sym == key
251
+ first = Hash[key, val]
252
+ elsif second_algorithm.to_sym == key
253
+ second = Hash[key, val]
254
+ end
255
+ end
256
+ {
257
+ first.keys[0] => first[first.keys[0]],
258
+ second.keys[0] => second[second.keys[0]]
259
+ }
260
+ end
261
+ end
262
+
263
+ # Stack data structure
264
+ # Worst-Case Space Complexity: O(n)
265
+ class Stack
266
+ def initialize(size, array=[])
267
+ @size = size
268
+ @store = Array.new(@size)
269
+ @top = -1
270
+ array.each { |el| push(el) }
271
+ end
272
+
273
+ # Search, Average-Case Time Complexity: O(n)
274
+ # Search, Worst-Case Time Complexity: O(n)
275
+ def search(target)
276
+ found = false
277
+ new_stack = Stack.new(@size)
278
+ until empty? do
279
+ new_stack.push(pop)
280
+ if new_stack.look == target
281
+ found = true
282
+ break
283
+ end
284
+ end
285
+ push(new_stack.pop) until new_stack.empty?
286
+ found
287
+ end
288
+
289
+ # Deletion, Worst-Case Time Complexity: O(1)
290
+ def pop
291
+ if empty?
292
+ nil
293
+ else
294
+ popped = @store[@top]
295
+ @store[@top] = nil
296
+ @top = @top.pred
297
+ popped
298
+ end
299
+ end
300
+
301
+ # Insertion, Worst-Case Time Complexity: O(1)
302
+ def push(el)
303
+ if full? or el.nil?
304
+ nil
305
+ else
306
+ @top = @top.succ
307
+ @store[@top] = el
308
+ self
309
+ end
310
+ end
311
+
312
+ def size
313
+ @size
314
+ end
315
+
316
+ def look
317
+ @store[@top]
318
+ end
319
+
320
+ def full?
321
+ @top == (@size - 1)
322
+ end
323
+
324
+ def empty?
325
+ @top == -1
326
+ end
327
+ end
328
+
329
+ # Queue data structure
330
+ # Worst-Case Space Complexity: O(n)
331
+ class Queue
332
+ def initialize(size, array=[])
333
+ @size = size
334
+ @store = Array.new(@size)
335
+ @head, @tail = -1, 0
336
+
337
+ # initialize Queue with array if given
338
+ array.each { |el| enqueue(el) }
339
+ end
340
+
341
+ # Search, Worst-Case Time Complexity: O(n)
342
+ def search(target)
343
+ found = false
344
+ @size.times do
345
+ found = true if look == target
346
+ enqueue(dequeue)
347
+ end
348
+ found
349
+ end
350
+
351
+ # Deletion, Worst-Case Time Complexity: O(1)
352
+ def dequeue
353
+ if empty?
354
+ nil
355
+ else
356
+ @tail = @tail.succ
357
+ dequeued = @store[@head]
358
+ @store.unshift(nil)
359
+ @store.pop
360
+ dequeued
361
+ end
362
+ end
363
+
364
+ # Insertion, Worst-Case Time Complexity: O(1)
365
+ def enqueue(el)
366
+ if full? or el.nil?
367
+ nil
368
+ else
369
+ @tail = @tail.pred
370
+ @store[@tail] = el
371
+ self
372
+ end
373
+ end
374
+
375
+ def size
376
+ @size
377
+ end
378
+
379
+ def look
380
+ @store[@head]
381
+ end
382
+
383
+ private
384
+
385
+ def empty?
386
+ @head == -1 and @tail == 0
387
+ end
388
+
389
+ def full?
390
+ @tail.abs == (@size)
391
+ end
392
+ end
393
+
394
+ # Singly-Linked List data structure
395
+ # Worst-Case Space Complexity: O(n)
396
+ class LinkedList
397
+ include Enumerable
398
+
399
+ def initialize(array=[])
400
+ @head = LinkNode.new
401
+ @tail = LinkNode.new
402
+ @head.next = @tail
403
+ @tail.prev = @head
404
+ array.each { |i| insert(i) }
405
+ end
406
+
407
+ # Search, Worst-Case Time Complexity: O(n)
408
+ def search(target)
409
+ each { |current_link| return current_link.val if current_link.val == target }
410
+ end
411
+
412
+ def [](i)
413
+ each_with_index { |link, j| return link if i == j }
414
+ nil
415
+ end
416
+
417
+ def first
418
+ empty? ? nil : @head.next
419
+ end
420
+
421
+ def last
422
+ empty? ? nil : @tail.prev
423
+ end
424
+
425
+ def empty?
426
+ @head.next == @tail
427
+ end
428
+
429
+ def get(val)
430
+ each { |link| return link.val if link.val == val }
431
+ nil
432
+ end
433
+
434
+ def include?(val)
435
+ any? { |link| link.val == val }
436
+ end
437
+
438
+ # Insertion, Worst-Case Time Complexity: O(1)
439
+ def insert(val)
440
+ each { |link| return link.val = val if link.val == val }
441
+ new_link = LinkNode.new(val)
442
+ @tail.prev.next = new_link
443
+ new_link.prev = @tail.prev
444
+ new_link.next = @tail
445
+ @tail.prev = new_link
446
+ new_link
447
+ end
448
+
449
+ # Deletion, Worst-Case Time Complexity: O(1)
450
+ def remove(val)
451
+ each do |link|
452
+ if link.val == val
453
+ link.prev.next = link.next
454
+ link.next.prev = link.prev
455
+ link.next, link.prev = nil, nil
456
+ return link.val
457
+ end
458
+ end
459
+ nil
460
+ end
461
+
462
+ def each
463
+ current_link = @head.next
464
+ until current_link == @tail
465
+ yield current_link
466
+ current_link = current_link.next
467
+ end
468
+ end
469
+ end
470
+
471
+ # Binary Search Tree data structure
472
+ # Worst-Case Space Complexity: O(n)
473
+ class BinaryTree
474
+ attr_accessor :root
475
+
476
+ def initialize(array=[], root_val=nil)
477
+ @root = BSTNode.new(root_val)
478
+ array.each { |i| insert(i) }
479
+ end
480
+
481
+ # Search, Worst-Case Time Complexity: O(n)
482
+ def search(target)
483
+ return nil if @root.nil?
484
+ return search_in_tree(@root, target)
485
+ end
486
+
487
+ def search_in_tree(tree_node, target)
488
+ return nil if tree_node.nil?
489
+ return tree_node.val if target == tree_node.val
490
+ if target < tree_node.val
491
+ search_in_tree(tree_node.left, target)
492
+ else
493
+ search_in_tree(tree_node.right, target)
494
+ end
495
+ end
496
+
497
+ # Insertion, Worst-Case Time Complexity: O(n)
498
+ def insert(val)
499
+ new_node = BSTNode.new(val)
500
+ @root = new_node and return unless @root.val
501
+ insert_to_tree(@root, new_node)
502
+ end
503
+
504
+ def insert_to_tree(tree_node, new_node)
505
+ tree_node = new_node and return if tree_node.nil?
506
+ return tree_node if tree_node.val == new_node.val
507
+ if new_node.val > tree_node.val
508
+ insert_to_tree(tree_node.right, new_node) unless tree_node.right.nil?
509
+ tree_node.right = new_node
510
+ else
511
+ insert_to_tree(tree_node.left, new_node) unless tree_node.left.nil?
512
+ tree_node.left = new_node
513
+ end
514
+ end
515
+ end
516
+
517
+ private
518
+
519
+ # Helper method to get time required for method to run
520
+ def display_time(prc, num_tests)
521
+ total = 0
522
+ num_tests.times do
523
+ start = Time.now
524
+ prc.call
525
+ finish = Time.now
526
+ total = total + (finish - start)
527
+ end
528
+ total/num_tests
529
+ end
530
+
531
+ # Helper method for merge_sort
532
+ def merge(left, right)
533
+ array = []
534
+ until left.length == 0 || right.length == 0
535
+ if left.first > right.first
536
+ array << right.shift
537
+ else
538
+ array << left.shift
539
+ end
540
+ end
541
+ array.concat(left).concat(right)
542
+ end
543
+
544
+ # Node helper class for Linked List
545
+ class LinkNode
546
+ attr_accessor :val, :next, :prev
547
+ def initialize(val=nil)
548
+ @val = val
549
+ @next = nil
550
+ @prev = nil
551
+ end
552
+ end
553
+
554
+ # Node helper class for Binary Search Tree
555
+ class BSTNode
556
+ attr_accessor :val, :left, :right
557
+ def initialize(val=nil, left=nil, right=nil)
558
+ @val = val
559
+ @left = left
560
+ @right = right
561
+ end
562
+ end