algorithmable 0.13.0 → 0.14.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/algorithmable.gemspec +1 -0
  4. data/lib/algorithmable/cache/imp.rb +19 -0
  5. data/lib/algorithmable/cache/primitive_max_heap.rb +38 -0
  6. data/lib/algorithmable/cache/primitive_min_heap.rb +38 -0
  7. data/lib/algorithmable/cache.rb +15 -0
  8. data/lib/algorithmable/cups/circular_dependencies.rb +27 -0
  9. data/lib/algorithmable/cups/longest_common_subsequence.rb +46 -0
  10. data/lib/algorithmable/cups/merge_two_arrays.rb +31 -0
  11. data/lib/algorithmable/cups/nested_lists_problem.rb +105 -0
  12. data/lib/algorithmable/cups/number_of_occurrences_in_array.rb +49 -0
  13. data/lib/algorithmable/cups/primitives.rb +205 -2
  14. data/lib/algorithmable/cups/root_cube_issue.rb +39 -0
  15. data/lib/algorithmable/cups/stacks_and_queues/stack_sorter.rb +25 -0
  16. data/lib/algorithmable/cups/stacks_and_queues/stack_with_min.rb +23 -0
  17. data/lib/algorithmable/cups/stacks_and_queues/towers_of_hanoi.rb +48 -0
  18. data/lib/algorithmable/cups/stacks_and_queues/triple_stack.rb +52 -0
  19. data/lib/algorithmable/cups/stacks_and_queues/two_stacks_queue.rb +37 -0
  20. data/lib/algorithmable/cups/stacks_and_queues.rb +31 -0
  21. data/lib/algorithmable/cups/stocks.rb +80 -0
  22. data/lib/algorithmable/cups/task_shedule_with_coldtime.rb +16 -0
  23. data/lib/algorithmable/cups/two_sum.rb +59 -0
  24. data/lib/algorithmable/cups.rb +7 -0
  25. data/lib/algorithmable/data_structs/linked_list/base.rb +21 -1
  26. data/lib/algorithmable/data_structs/linked_list/doubly.rb +1 -1
  27. data/lib/algorithmable/data_structs/linked_list/singly.rb +62 -1
  28. data/lib/algorithmable/data_structs/queue.rb +4 -0
  29. data/lib/algorithmable/data_structs/stack.rb +4 -0
  30. data/lib/algorithmable/data_structs/tree/binary.rb +10 -0
  31. data/lib/algorithmable/data_structs/tree/binary_search.rb +206 -0
  32. data/lib/algorithmable/data_structs/tree.rb +13 -0
  33. data/lib/algorithmable/data_structs.rb +6 -0
  34. data/lib/algorithmable/sort/bubble.rb +9 -16
  35. data/lib/algorithmable/sort/insertion.rb +24 -0
  36. data/lib/algorithmable/sort/merge.rb +4 -8
  37. data/lib/algorithmable/sort/quick_sort.rb +35 -0
  38. data/lib/algorithmable/sort/selection.rb +23 -0
  39. data/lib/algorithmable/sort/shell.rb +27 -0
  40. data/lib/algorithmable/sort/shuffle.rb +15 -0
  41. data/lib/algorithmable/sort/utils.rb +66 -0
  42. data/lib/algorithmable/sort.rb +28 -0
  43. data/lib/algorithmable/union_find.rb +51 -0
  44. data/lib/algorithmable/version.rb +1 -1
  45. data/lib/algorithmable.rb +2 -0
  46. data/script/benchmarks/sort.rb +37 -0
  47. metadata +46 -2
@@ -0,0 +1,35 @@
1
+ module Algorithmable
2
+ module Sort
3
+ class QuickSort
4
+ extend Algorithmable::Sort::Utils
5
+
6
+ def self.sort(collection)
7
+ do_effect(collection, 0, collection.length - 1)
8
+ end
9
+
10
+ private
11
+
12
+ def self.do_effect(collection, lo, hi)
13
+ return collection if hi <= lo
14
+ lo_or_hi = partition(collection, lo, hi)
15
+ do_effect(collection, lo, lo_or_hi - 1)
16
+ do_effect(collection, lo_or_hi + 1, hi)
17
+ end
18
+
19
+ # private
20
+ #
21
+ # def self.partition(ary, from, to)
22
+ # pivot = ary[from]
23
+ # i = from + 1
24
+ # (from + 1).upto(to).each do |j|
25
+ # if ary[j] < pivot
26
+ # ary[i], ary[j] = ary[j], ary[i]
27
+ # i += 1
28
+ # end
29
+ # end
30
+ # ary[i-1], ary[from] = ary[from], ary[i-1]
31
+ # i
32
+ # end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ module Algorithmable
2
+ module Sort
3
+ class Selection
4
+ extend Algorithmable::Sort::Utils
5
+ # Does sorting in O(n2) time (quadratic time)
6
+ #
7
+ def self.sort(collection)
8
+ return collection if collection.empty? || 1 >= collection.length
9
+ length = collection.length - 1
10
+
11
+ 0.upto(length).each do |i|
12
+ min = i
13
+ (1 + i).upto(length).each do |j|
14
+ min = j if collection[j] < collection[min]
15
+ end
16
+ exchange(i, min, collection)
17
+ end
18
+
19
+ collection
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ module Algorithmable
2
+ module Sort
3
+ class Shell
4
+ extend Algorithmable::Sort::Utils
5
+ def self.sort(collection)
6
+ return collection if 2 > collection.length
7
+ length = collection.length
8
+ h = 1
9
+
10
+ h = 3 * h + 1 while h < length / 3
11
+
12
+ while h >= 1
13
+ h.upto(length - 1).each do |i|
14
+ j = i
15
+ while j >= h && collection[j] < collection[j - h]
16
+ exchange(j, j - h, collection)
17
+ j -= h
18
+ end
19
+ end
20
+ h /= 3
21
+ end
22
+
23
+ collection
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ module Algorithmable
2
+ module Sort
3
+ class Shuffle
4
+ extend Algorithmable::Sort::Utils
5
+
6
+ def self.sort(collection)
7
+ return collection if collection.empty? || 2 > collection.length
8
+ collection.length.times do |i|
9
+ exchange(i, rand(i + 1), collection)
10
+ end
11
+ collection
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,66 @@
1
+ module Algorithmable
2
+ module Sort
3
+ module Utils
4
+ # @param [Integer] a
5
+ # @param [Integer] bottom
6
+ # @param [Array] top
7
+ # @return [Integer] Integer representing new pivot location
8
+ def partition(a, bottom, top)
9
+ i = bottom
10
+ j = top.succ
11
+ v = a[bottom]
12
+ loop do
13
+ while a[i += 1] < v
14
+ break if i == top
15
+ end
16
+ while v < a[j -= 1]
17
+ break if j == bottom
18
+ end
19
+ break if i >= j
20
+ cur_i = a[i]
21
+ a[i] = a[j]
22
+ a[j] = cur_i
23
+ end
24
+ cur_bottom = a[bottom]
25
+ a[bottom] = a[j]
26
+ a[j] = cur_bottom
27
+ j
28
+ end
29
+
30
+ # def partition(ary, from, to)
31
+ # pivot = ary[from]
32
+ # i = from + 1
33
+ # (from + 1).upto(to).each do |j|
34
+ # if ary[j] < pivot
35
+ # ary[i], ary[j] = ary[j], ary[i]
36
+ # i += 1
37
+ # end
38
+ # end
39
+ # ary[i-1], ary[from] = ary[from], ary[i-1]
40
+ # i
41
+ # end
42
+
43
+ # @param [Integer] from
44
+ # @param [Integer] to
45
+ # @param [Array] collection
46
+ # @return [Object]
47
+ def exchange(from, to, collection)
48
+ return collection if from == to
49
+ local_from = collection[from]
50
+ collection[from] = collection[to]
51
+ collection[to] = local_from
52
+ collection
53
+ end
54
+
55
+ # @param [Integer] collection
56
+ # @param [Integer] i
57
+ # @return [Array] collection
58
+ def swap(collection, i)
59
+ current = collection[i]
60
+ collection[i] = collection[i + 1]
61
+ collection[i + 1] = current
62
+ collection
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,10 +1,22 @@
1
1
  module Algorithmable
2
2
  module Sort
3
+ autoload :Utils, 'algorithmable/sort/utils'
4
+ autoload :Selection, 'algorithmable/sort/selection'
5
+ autoload :Insertion, 'algorithmable/sort/insertion'
6
+ autoload :Shell, 'algorithmable/sort/shell'
7
+ autoload :Shuffle, 'algorithmable/sort/shuffle'
3
8
  autoload :Merge, 'algorithmable/sort/merge'
4
9
  autoload :Bubble, 'algorithmable/sort/bubble'
5
10
  autoload :BinaryHeap, 'algorithmable/sort/binary_heap'
11
+ autoload :QuickSort, 'algorithmable/sort/quick_sort'
12
+
13
+ private_constant :Merge, :Bubble, :BinaryHeap, :Insertion, :QuickSort, :Selection
6
14
 
7
15
  class << self
16
+ def quick(collection)
17
+ QuickSort.sort(collection)
18
+ end
19
+
8
20
  def merge(collection)
9
21
  Merge.sort(collection)
10
22
  end
@@ -16,6 +28,22 @@ module Algorithmable
16
28
  def binary_heap(collection)
17
29
  BinaryHeap.sort(collection)
18
30
  end
31
+
32
+ def selection(container)
33
+ Selection.sort(container)
34
+ end
35
+
36
+ def insertion(collection)
37
+ Insertion.sort(collection)
38
+ end
39
+
40
+ def shell(collection)
41
+ Shell.sort(collection)
42
+ end
43
+
44
+ def shuffle(collection)
45
+ Shuffle.sort(collection)
46
+ end
19
47
  end
20
48
  end
21
49
  end
@@ -0,0 +1,51 @@
1
+ module Algorithmable
2
+ module UnionFind
3
+ def self.new(quantity)
4
+ Impl.new(quantity)
5
+ end
6
+
7
+ class Impl
8
+ attr_reader :quantity
9
+
10
+ def initialize(quantity, find_strategy = SimpleFind.new, union_strategy = SimpleUnion.new)
11
+ @index = (0..quantity).to_a
12
+ @quantity = quantity
13
+ @find_strategy = find_strategy
14
+ @union_strategy = union_strategy
15
+ end
16
+
17
+ def find(p)
18
+ @find_strategy.find(p, @index)
19
+ end
20
+
21
+ def union(p1, p2)
22
+ @union_strategy.union(p1, p2, @index)
23
+ @quantity -= 1
24
+ end
25
+
26
+ def connected?(p1, p2)
27
+ find(p1) == find(p2)
28
+ end
29
+ end
30
+
31
+ class SimpleFind
32
+ def find(p, collection)
33
+ collection[p]
34
+ end
35
+ end
36
+
37
+ class SimpleUnion
38
+ def union(p1, p2, collection)
39
+ p1_id = collection[p1]
40
+ p2_id = collection[p2]
41
+ return collection if p1_id == p2_id
42
+ collection.each_index do |i|
43
+ collection[i] = p2_id if collection[i] == p1_id
44
+ end
45
+ collection
46
+ end
47
+ end
48
+
49
+ private_constant :Impl, :SimpleFind, :SimpleUnion
50
+ end
51
+ end
@@ -1,3 +1,3 @@
1
1
  module Algorithmable
2
- VERSION = '0.13.0'
2
+ VERSION = '0.14.0'
3
3
  end
data/lib/algorithmable.rb CHANGED
@@ -13,6 +13,8 @@ module Algorithmable
13
13
  autoload :Puzzles, 'algorithmable/puzzles'
14
14
  autoload :LevenshteinDistance, 'algorithmable/levenshtein_distance'
15
15
  autoload :Cups, 'algorithmable/cups'
16
+ autoload :Cache, 'algorithmable/cache'
17
+ autoload :UnionFind, 'algorithmable/union_find'
16
18
 
17
19
  class << self
18
20
  def logger
@@ -0,0 +1,37 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'algorithmable'
5
+ require 'rbench'
6
+
7
+ job = lambda do |*_args|
8
+ sorter = Algorithmable::Sort
9
+ n = 1000
10
+ column_names = %w(selection insertion shell bubble merge quick binary_heap ruby)
11
+
12
+ f = -> (name) { public_send :column, name.to_sym }
13
+ column_names.each(&f)
14
+
15
+ g = lambda do |scope, ary|
16
+ scope.selection { sorter.selection(ary.dup) }
17
+ scope.insertion { sorter.insertion(ary.dup) }
18
+ scope.shell { sorter.shell(ary.dup) }
19
+ scope.bubble { sorter.bubble(ary.dup) }
20
+ scope.merge { sorter.merge(ary.dup) }
21
+ scope.quick { sorter.quick(ary.dup) }
22
+ scope.binary_heap { sorter.binary_heap(ary.dup) }
23
+ scope.ruby { ary.dup.sort }
24
+ end
25
+
26
+ report :presorted do
27
+ sorted_array = (0..n).to_a
28
+ g.call(self, sorted_array)
29
+ end
30
+
31
+ report :shuffled do
32
+ random_array = (0..n).to_a.shuffle
33
+ g.call(self, random_array)
34
+ end
35
+ end
36
+
37
+ RBench.run(5, &job)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: algorithmable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Lishtaba
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-01-17 00:00:00.000000000 Z
11
+ date: 2016-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.8'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rbench
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'
125
139
  description: Useful algorithms for everyday usage implemented using Ruby.
126
140
  email:
127
141
  - roman@lishtaba.com
@@ -140,8 +154,27 @@ files:
140
154
  - algorithmable.gemspec
141
155
  - cucumber.yml
142
156
  - lib/algorithmable.rb
157
+ - lib/algorithmable/cache.rb
158
+ - lib/algorithmable/cache/imp.rb
159
+ - lib/algorithmable/cache/primitive_max_heap.rb
160
+ - lib/algorithmable/cache/primitive_min_heap.rb
143
161
  - lib/algorithmable/cups.rb
162
+ - lib/algorithmable/cups/circular_dependencies.rb
163
+ - lib/algorithmable/cups/longest_common_subsequence.rb
164
+ - lib/algorithmable/cups/merge_two_arrays.rb
165
+ - lib/algorithmable/cups/nested_lists_problem.rb
166
+ - lib/algorithmable/cups/number_of_occurrences_in_array.rb
144
167
  - lib/algorithmable/cups/primitives.rb
168
+ - lib/algorithmable/cups/root_cube_issue.rb
169
+ - lib/algorithmable/cups/stacks_and_queues.rb
170
+ - lib/algorithmable/cups/stacks_and_queues/stack_sorter.rb
171
+ - lib/algorithmable/cups/stacks_and_queues/stack_with_min.rb
172
+ - lib/algorithmable/cups/stacks_and_queues/towers_of_hanoi.rb
173
+ - lib/algorithmable/cups/stacks_and_queues/triple_stack.rb
174
+ - lib/algorithmable/cups/stacks_and_queues/two_stacks_queue.rb
175
+ - lib/algorithmable/cups/stocks.rb
176
+ - lib/algorithmable/cups/task_shedule_with_coldtime.rb
177
+ - lib/algorithmable/cups/two_sum.rb
145
178
  - lib/algorithmable/data_structs.rb
146
179
  - lib/algorithmable/data_structs/bag.rb
147
180
  - lib/algorithmable/data_structs/deque.rb
@@ -156,6 +189,9 @@ files:
156
189
  - lib/algorithmable/data_structs/ordered_symbol_table.rb
157
190
  - lib/algorithmable/data_structs/queue.rb
158
191
  - lib/algorithmable/data_structs/stack.rb
192
+ - lib/algorithmable/data_structs/tree.rb
193
+ - lib/algorithmable/data_structs/tree/binary.rb
194
+ - lib/algorithmable/data_structs/tree/binary_search.rb
159
195
  - lib/algorithmable/errors.rb
160
196
  - lib/algorithmable/graphs.rb
161
197
  - lib/algorithmable/graphs/traversals.rb
@@ -172,8 +208,16 @@ files:
172
208
  - lib/algorithmable/sort.rb
173
209
  - lib/algorithmable/sort/binary_heap.rb
174
210
  - lib/algorithmable/sort/bubble.rb
211
+ - lib/algorithmable/sort/insertion.rb
175
212
  - lib/algorithmable/sort/merge.rb
213
+ - lib/algorithmable/sort/quick_sort.rb
214
+ - lib/algorithmable/sort/selection.rb
215
+ - lib/algorithmable/sort/shell.rb
216
+ - lib/algorithmable/sort/shuffle.rb
217
+ - lib/algorithmable/sort/utils.rb
218
+ - lib/algorithmable/union_find.rb
176
219
  - lib/algorithmable/version.rb
220
+ - script/benchmarks/sort.rb
177
221
  - script/console
178
222
  homepage: ''
179
223
  licenses: