algorithm_selector 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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