algorithmable 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -3,7 +3,7 @@ module Algorithmable
3
3
  module LinkedList
4
4
  class Doubly < Base
5
5
  class Node
6
- attr_accessor :item, :prev, :next
6
+ attr_accessor :item, :prev, :next, :front
7
7
 
8
8
  def initialize(item, prev_pointer = nil, next_pointer = nil)
9
9
  @item = item
@@ -3,7 +3,7 @@ module Algorithmable
3
3
  module LinkedList
4
4
  class Singly < Base
5
5
  class Node
6
- attr_accessor :item, :next
6
+ attr_accessor :item, :next, :front
7
7
 
8
8
  def initialize(item, next_pointer = nil)
9
9
  @item = item
@@ -93,8 +93,69 @@ module Algorithmable
93
93
  end
94
94
  end
95
95
 
96
+ def merge(other)
97
+ front = recursive_merge_imp self.front, other.front
98
+ list = self.class.new
99
+ while front
100
+ list.push_back front.item
101
+ front = front.next
102
+ end
103
+ list
104
+ end
105
+
106
+ def reverse!
107
+ @back = @front
108
+ @front = reverse_imp @front
109
+ self
110
+ end
111
+
112
+ def sort!
113
+ sort_linked_list @front
114
+ end
115
+
96
116
  private
97
117
 
118
+ def sort_linked_list(node)
119
+ return unless node || node.empty?
120
+ swapped = false
121
+ prev = nil
122
+
123
+ begin
124
+ swapped = false
125
+ current = node
126
+
127
+ until current.next == prev
128
+ if current.item > current.next.item
129
+ swap_nodes current, current.next
130
+ swapped = true
131
+ end
132
+ current = current.next
133
+ end
134
+
135
+ prev = current
136
+ end while swapped
137
+ end
138
+
139
+ def swap_nodes(node1, node2)
140
+ tmp = node1.item
141
+ node1.item = node2.item
142
+ node2.item = tmp
143
+ end
144
+
145
+ def recursive_merge_imp(node1, node2)
146
+ return node2 if node1.nil?
147
+ return node1 if node2.nil?
148
+ node1 = node1.dup
149
+ node2 = node2.dup
150
+ if node1.item < node2.item
151
+ node1.next = recursive_merge_imp(node1.next, node2)
152
+ node1
153
+ else
154
+ node2.next = recursive_merge_imp(node2.next, node1)
155
+ node2
156
+ end
157
+ end
158
+
98
159
  def reverse_imp(root)
99
160
  return root if root.nil? || root.next.nil?
100
161
  node = reverse_imp(root.next)
@@ -23,6 +23,10 @@ module Algorithmable
23
23
  def dequeue
24
24
  @imp.pop_front
25
25
  end
26
+
27
+ def to_s
28
+ to_a.join('->')
29
+ end
26
30
  end
27
31
  end
28
32
  end
@@ -24,6 +24,10 @@ module Algorithmable
24
24
  def pop
25
25
  @imp.pop_front
26
26
  end
27
+
28
+ def to_s
29
+ to_a.join '->'
30
+ end
27
31
  end
28
32
  end
29
33
  end
@@ -0,0 +1,10 @@
1
+ module Algorithmable
2
+ module DataStructs
3
+ module Tree
4
+ class Binary
5
+ include Enumerable
6
+ include Algorithmable::DataStructs
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,206 @@
1
+ module Algorithmable
2
+ module DataStructs
3
+ module Tree
4
+ class BinarySearch
5
+ include Enumerable
6
+ include Algorithmable::DataStructs
7
+
8
+ def initialize(collection = [])
9
+ @root = nil
10
+ collection.each { |item| put item }
11
+ end
12
+
13
+ def max_depth
14
+ max_height_of @root
15
+ end
16
+
17
+ alias_method :height, :max_depth
18
+
19
+ def min_depth
20
+ min_height_of @root
21
+ end
22
+
23
+ def size
24
+ size_of @root
25
+ end
26
+
27
+ def empty?
28
+ 0 == size
29
+ end
30
+
31
+ def put(object)
32
+ @root = put_impl @root, object
33
+ end
34
+
35
+ def min
36
+ return if empty?
37
+ min_impl(@root).item
38
+ end
39
+
40
+ def max
41
+ return if empty?
42
+ max_impl(@root).item
43
+ end
44
+
45
+ def each(&block)
46
+ each_with_dfs(&block)
47
+ end
48
+
49
+ def each_with_dfs(&block)
50
+ tmp = collect_nodes_with_dfs(@root).to_a
51
+ block_given? ? tmp.each(&block) : tmp
52
+ end
53
+
54
+ def each_with_bfs(&block)
55
+ tmp = collect_nodes_with_bfs(@root).to_a
56
+ block_given? ? tmp.each(&block) : tmp
57
+ end
58
+
59
+ def to_print
60
+ return if empty?
61
+ queue = new_fifo_queue
62
+ level = 0
63
+ next_level = 1
64
+ out = []
65
+ queue.enqueue @root
66
+ until queue.empty?
67
+ level += 1
68
+ node = queue.dequeue
69
+ out << node.item << ' '
70
+ queue.enqueue node.left if node.left
71
+ queue.enqueue node.right if node.right
72
+
73
+ if level == next_level
74
+ next_level += queue.size
75
+ out << "\n"
76
+ end
77
+ end
78
+ out.join
79
+ end
80
+
81
+ def reverse!
82
+ @root = reverse_bang_impl @root
83
+ end
84
+
85
+ def flip!
86
+ @root = flip_bang_imp! @root, 0
87
+ end
88
+
89
+ def flip_bang_imp!(n, count)
90
+ return unless n
91
+ return n unless n.left && n.right
92
+ new_head = flip_bang_imp! n.left, count + 1
93
+ n.left.left = n.right
94
+ n.left.right = n
95
+ if count == 0
96
+ n.left = nil
97
+ n.right = nil
98
+ end
99
+ new_head
100
+ end
101
+
102
+ def balanced?(diff = 1)
103
+ (max_depth - min_depth) <= diff
104
+ end
105
+
106
+ private
107
+
108
+ def max_height_of(node)
109
+ return 0 unless node
110
+ 1 + [max_height_of(node.left), max_height_of(node.right)].max
111
+ end
112
+
113
+ def min_height_of(node)
114
+ return 0 unless node
115
+ 1 + [min_height_of(node.left), min_height_of(node.right)].min
116
+ end
117
+
118
+ def reverse_bang_impl(root)
119
+ return unless root
120
+ reverse_bang_impl root.left
121
+ reverse_bang_impl root.right
122
+ tmp = root.left
123
+ root.left = root.right
124
+ root.right = tmp
125
+ root
126
+ end
127
+
128
+ def collect_nodes_with_bfs(root)
129
+ queue = new_fifo_queue
130
+ stack = new_lifo_queue
131
+ queue.enqueue root
132
+ until queue.empty?
133
+ node = queue.dequeue
134
+ stack.push node.item
135
+ queue.enqueue node.left if node.left
136
+ queue.enqueue node.right if node.right
137
+ end
138
+ stack
139
+ end
140
+
141
+ def collect_nodes_with_dfs(node)
142
+ stack = []
143
+ dfs_impl node, stack
144
+ stack
145
+ end
146
+
147
+ # in-order traversal
148
+ def dfs_impl(node, stack)
149
+ dfs_impl node.left, stack if node.left
150
+ stack.push node.item
151
+ dfs_impl node.right, stack if node.right
152
+ end
153
+
154
+ def max_impl(node)
155
+ return node if node.right.nil?
156
+ max_impl(node.right)
157
+ end
158
+
159
+ def min_impl(node)
160
+ return node if node.left.nil?
161
+ min_impl(node.left)
162
+ end
163
+
164
+ def put_impl(node, object)
165
+ return make_node(object, 1) unless node
166
+ case object <=> node.item
167
+ when -1
168
+ node.left = put_impl(node.left, object)
169
+ when 1
170
+ node.right = put_impl(node.right, object)
171
+ else
172
+ node.item = object
173
+ end
174
+ node.size = 1 + size_of(node.left) + size_of(node.right)
175
+ node
176
+ end
177
+
178
+ def size_of(node)
179
+ return 0 if node.nil?
180
+ node.size
181
+ end
182
+
183
+ def make_node(object, size)
184
+ Node.new object, size
185
+ end
186
+
187
+ class Node
188
+ attr_accessor :item, :left, :right, :size
189
+
190
+ def initialize(value, size)
191
+ @item = value
192
+ @size = size
193
+ @left = nil
194
+ @right = nil
195
+ end
196
+
197
+ def <=>(other)
198
+ @item <=> other.item
199
+ end
200
+ end
201
+
202
+ private_constant :Node
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,13 @@
1
+ module Algorithmable
2
+ module DataStructs
3
+ module Tree
4
+ autoload :Binary, 'algorithmable/data_structs/tree/binary'
5
+ autoload :BinarySearch, 'algorithmable/data_structs/tree/binary_search'
6
+ autoload :Node, 'algorithmable/data_structs/tree/node'
7
+
8
+ def new_ordered_binary_tree(collection = [])
9
+ BinarySearch.new(collection)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -7,8 +7,10 @@ module Algorithmable
7
7
  autoload :Stack, 'algorithmable/data_structs/stack'
8
8
  autoload :OrderedSymbolTable, 'algorithmable/data_structs/ordered_symbol_table'
9
9
  autoload :Heap, 'algorithmable/data_structs/heap'
10
+ autoload :Tree, 'algorithmable/data_structs/tree'
10
11
 
11
12
  include LinkedList
13
+ include Tree
12
14
 
13
15
  def new_bag
14
16
  Bag.new
@@ -22,6 +24,10 @@ module Algorithmable
22
24
  Stack.new
23
25
  end
24
26
 
27
+ def new_deque_queue
28
+ Deque.new
29
+ end
30
+
25
31
  def new_ordered_symbol_table(key_type, value_type)
26
32
  OrderedSymbolTable.new(key_type, value_type)
27
33
  end
@@ -1,16 +1,18 @@
1
1
  module Algorithmable
2
2
  module Sort
3
3
  class Bubble
4
+ extend Algorithmable::Sort::Utils
5
+ #
6
+ # Time О(N^2), stable and slow
7
+ # Space О(N)
8
+ #
4
9
  def self.sort(collection)
5
- new.sort(collection)
6
- end
7
-
8
- def sort(collection)
10
+ length = collection.length - 1
9
11
  loop do
10
12
  swapped = false
11
- (collection.size.pred).times do |index|
12
- if (collection[index] <=> collection[index.next]) == 1
13
- collection = swap(index, collection)
13
+ 0.upto(length).each do |i|
14
+ if 1 == (collection[i] <=> collection[i + 1])
15
+ swap(collection, i)
14
16
  swapped = true
15
17
  end
16
18
  end
@@ -18,15 +20,6 @@ module Algorithmable
18
20
  end
19
21
  collection
20
22
  end
21
-
22
- private
23
-
24
- def swap(index, collection)
25
- current = collection[index]
26
- collection[index] = collection[index.next]
27
- collection[index.next] = current
28
- collection
29
- end
30
23
  end
31
24
  end
32
25
  end
@@ -0,0 +1,24 @@
1
+ module Algorithmable
2
+ module Sort
3
+ class Insertion
4
+ extend Algorithmable::Sort::Utils
5
+ #
6
+ # Time О(N^2), stable and slow
7
+ # Space Complexity: О(N)
8
+ #
9
+ def self.sort(collection)
10
+ return collection if 2 > collection.length
11
+ 1.upto(collection.length - 1).each do |i|
12
+ curr_char = collection[i]
13
+ j = i - 1
14
+ while 0 <= j && collection[j] > curr_char
15
+ collection[j + 1] = collection[j]
16
+ j -= 1
17
+ end
18
+ collection[j + 1] = curr_char
19
+ end
20
+ collection
21
+ end
22
+ end
23
+ end
24
+ end
@@ -2,20 +2,16 @@ module Algorithmable
2
2
  module Sort
3
3
  class Merge
4
4
  def self.sort(collection)
5
- new.sort(collection)
6
- end
7
-
8
- def sort(collection)
9
- return collection if collection.size <= 1
10
- mid = collection.size / 2
5
+ return collection if collection.length <= 1
6
+ mid = collection.length / 2
11
7
  left = collection[0...mid]
12
- right = collection[mid...collection.size]
8
+ right = collection[mid...collection.length]
13
9
  merge(sort(left), sort(right))
14
10
  end
15
11
 
16
12
  private
17
13
 
18
- def merge(left, right)
14
+ def self.merge(left, right)
19
15
  sorted = []
20
16
  until left.empty? || right.empty?
21
17
  left.first <= right.first ? sorted << left.shift : sorted << right.shift