algorithmable 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 210c9d66c15c6f091c2db2be2063d72db3243051
4
- data.tar.gz: fba5ab243cfe9ce27ae93834b16ffb4500f6bcf3
3
+ metadata.gz: 3d896f5d72bec04a61e50d79c670e1ed9379b8cd
4
+ data.tar.gz: 701a49b6cb2d478a817baaef1ce743498a62813b
5
5
  SHA512:
6
- metadata.gz: 7dcddf1680bf74c69b2901e5867d3f2b1c7ff774b5386ed5c59dcc8449d6cc9a52f36478ad3876141fee89e541c2fb71b138ebcf6079ca8d2126f31e4a02050a
7
- data.tar.gz: 5fb2fffdacf63cd41aff9436bce9226f8672139e23e01df6bcc3f580914ec204289d99c1ad94610a0d1b9288bf4a0f621dc547d060c462e9943d7c88b5c22be3
6
+ metadata.gz: 45b738fc98edaaf14ee58050bdf24f8d78345fcda7b6d06394d1d6d9cc26dbb9151ea6832f27a3fd05d4906b1c9e80e7fb3d2684e70080574edb1aeacf12e4ab
7
+ data.tar.gz: 404eca38ab9c2775ba3f07d6760f2f37cbf303d5b59f36bbbf6fc03af59abe028d3b8bed31ada0c2b747f15eb5eefa92fec78cad1a0bbdaaa9e4c94b0446acfb
data/README.md CHANGED
@@ -2,7 +2,45 @@
2
2
 
3
3
  # Algorithmable
4
4
 
5
- Useful algorithms such as Sorting, Searches, Graph Traversal strategies & data structures such as Symbol Tables, BST, Hash Tables, Bag, Linked List, Queue, Stack, Graphs for everyday usage. Implemented using Ruby, for fun.
5
+ Useful algorithms such as Sorting Strategies, Searches and Data Structures such as symbol tables, binary search tree BST, red black tree RBT,
6
+ hash tables, bag, linked list, deque, queue FIFO, stack LIFO, graphs & Graph Traversal strategies for everyday usage.
7
+
8
+ Algorithms and Data Structures implemented using Ruby, for fun.
9
+
10
+ Library also contains solutions for several puzzles solved by implemented algorithms and data structures.
11
+
12
+ ## Data Structures
13
+
14
+ - Bag (primitive collection without ability to delete elements)
15
+ - Doubly Linked List
16
+ - Deque (double-ended queue)
17
+ - Queue (FIFO)
18
+ - Stack (LIFO)
19
+ - Ordered Symbol Table BST. Implementation using Unbalanced Binary Search Tree.
20
+
21
+ ## Graphs
22
+
23
+ - Undirected graph
24
+
25
+ ## Graph Traversals
26
+
27
+ - Breadth First Search (BFS)
28
+ - Death First Search (DFS)
29
+
30
+ ## Search Algorithms
31
+
32
+ - Binary Search
33
+
34
+ ## Sorting Algorithms
35
+
36
+ - Bubble sort
37
+ - Merge sort
38
+ - Heapsort ( Binary Heap )
39
+
40
+ # Usage
41
+
42
+ It is always better to check unit tests in order to understand how things going on.
43
+ Most of the components are encapsulated through the factory methods, so the are could be mixed to other objects.
6
44
 
7
45
  ## Installation
8
46
 
@@ -20,8 +58,6 @@ Or install it yourself as:
20
58
 
21
59
  $ gem install algorithmable
22
60
 
23
- ## Usage
24
-
25
61
  ## Contributing
26
62
 
27
63
  Bug reports and pull requests are welcome on GitHub at https://github.com/rlishtaba/algorithmable. 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.
@@ -0,0 +1,240 @@
1
+ module Algorithmable
2
+ module DataStructs
3
+ #
4
+ # Ordered Symbol Table. Implementation using Unbalanced Binary Tree.
5
+ #
6
+ class OrderedSymbolTable
7
+ def initialize(key_type, value_type)
8
+ @key_type = key_type
9
+ @value_type = value_type
10
+ @root = nil
11
+ end
12
+
13
+ def empty?
14
+ !size.nonzero?
15
+ end
16
+
17
+ def size
18
+ node_size(@root)
19
+ end
20
+
21
+ def key?(key)
22
+ assert_key_type(key)
23
+ !self[key].nil?
24
+ end
25
+
26
+ def [](key)
27
+ assert_key_type(key)
28
+ impl_get(@root, key)
29
+ end
30
+
31
+ def []=(key, value)
32
+ assert_value_type(value)
33
+ assert_key_type(key)
34
+ delete key
35
+ @root = impl_put(@root, key, value)
36
+ check_tree
37
+ end
38
+
39
+ def delete_min
40
+ @root = impl_delete_min @root
41
+ check_tree
42
+ end
43
+
44
+ def delete_max
45
+ @root = impl_delete_max @root
46
+ check_tree
47
+ end
48
+
49
+ def delete(key)
50
+ assert_key_type(key)
51
+ @root = impl_delete(@root, key)
52
+ check_tree
53
+ end
54
+
55
+ def min
56
+ impl_min(@root).key
57
+ end
58
+
59
+ def max
60
+ impl_max(@root).key
61
+ end
62
+
63
+ def floor(key)
64
+ assert_key_type(key)
65
+ return unless key || empty?
66
+ found = impl_floor(@root, key)
67
+ return unless found
68
+ found.key
69
+ end
70
+
71
+ def ceiling(key)
72
+ assert_key_type(key)
73
+ return unless key || empty?
74
+ found = impl_ceiling(@root, key)
75
+ return unless found
76
+ found.key
77
+ end
78
+
79
+ def select(integer)
80
+ return if integer < 0 || integer >= size
81
+ found = impl_select(@root, integer)
82
+ found.key
83
+ end
84
+
85
+ def rank(key)
86
+ assert_key_type(key)
87
+ return unless key
88
+ impl_rank @root, key
89
+ end
90
+
91
+ private
92
+
93
+ def check_tree
94
+ true
95
+ end
96
+
97
+ def assert_value_type(value)
98
+ fail "Type expectation not met. Use value type `#{@value_type}` instead." unless value.is_a? @value_type
99
+ end
100
+
101
+ def assert_key_type(key)
102
+ fail "Type expectation not met. Use key type `#{@key_type}` instead." unless key.is_a? @key_type
103
+ end
104
+
105
+ def impl_rank(node, key)
106
+ return 0 unless node
107
+ comparison = key <=> node.key
108
+ if comparison < 0
109
+ impl_rank(node.left, key)
110
+ elsif comparison > 0
111
+ 1 + node_size(node.left) + impl_rank(node.right, key)
112
+ else
113
+ node_size node.left
114
+ end
115
+ end
116
+
117
+ def impl_select(node, index)
118
+ return unless node
119
+ left_size = node_size(node.left)
120
+ if left_size > index
121
+ impl_select(node.left, index)
122
+ elsif left_size < index
123
+ impl_select node.right, (index - left_size - 1)
124
+ else
125
+ node
126
+ end
127
+ end
128
+
129
+ def impl_ceiling(node, key)
130
+ return unless node
131
+ comparison = key <=> node.key
132
+ return node if 0 == comparison
133
+ if comparison < 0
134
+ found = impl_ceiling(node.left, key)
135
+ return found if found
136
+ return node
137
+ end
138
+ impl_ceiling node.right, key
139
+ end
140
+
141
+ def impl_floor(node, key)
142
+ return unless node
143
+ comparison = key <=> node.key
144
+ return node if 0 == comparison
145
+ return impl_floor(node.left, key) if comparison < 0
146
+ found = impl_floor(node.right, key)
147
+ return found if found
148
+ node
149
+ end
150
+
151
+ def impl_delete(node, key)
152
+ return unless node
153
+ comparison = key <=> node.key
154
+ if comparison < 0
155
+ node.left = impl_delete(node.left, key)
156
+ elsif comparison > 0
157
+ node.right = impl_delete(node.right, key)
158
+ else
159
+ return unless node.left || node.right
160
+ temp = node
161
+ node = impl_min(temp.right)
162
+ node.right = impl_delete_min(temp.right)
163
+ node.left = temp.left
164
+ end
165
+ node.size = computed_node_size(node)
166
+ node
167
+ end
168
+
169
+ def impl_max(node)
170
+ return node unless node.right
171
+ impl_max node.right
172
+ end
173
+
174
+ def impl_min(node)
175
+ return node unless node.left
176
+ impl_min node.left
177
+ end
178
+
179
+ def impl_delete_max(node)
180
+ return node.left unless node.right
181
+ node.right = impl_delete_max(node.right)
182
+ node.size = computed_node_size(node)
183
+ node
184
+ end
185
+
186
+ def impl_delete_min(node)
187
+ return node.right unless node.left
188
+ node.left = impl_delete_min(node.left)
189
+ node.size = computed_node_size(node)
190
+ node
191
+ end
192
+
193
+ def impl_put(node, key, value)
194
+ return Node.new(key, value, 1) unless node
195
+ comparison = key <=> node.key
196
+ if comparison < 0
197
+ node.left = impl_put(node.left, key, value)
198
+ elsif comparison > 0
199
+ node.right = impl_put(node.right, key, value)
200
+ else
201
+ node.value = value
202
+ end
203
+ node.size = computed_node_size(node)
204
+ node
205
+ end
206
+
207
+ def impl_get(node, key)
208
+ return unless node
209
+ comparison = key <=> node.key
210
+ if comparison < 0
211
+ impl_get(node.left, key)
212
+ elsif comparison > 0
213
+ impl_get(node.right, key)
214
+ else
215
+ node.value
216
+ end
217
+ end
218
+
219
+ def node_size(node)
220
+ node.nil? ? 0 : node.size
221
+ end
222
+
223
+ def computed_node_size(node)
224
+ 1 + node_size(node.left) + node_size(node.right)
225
+ end
226
+
227
+ class Node
228
+ attr_accessor :key, :value, :left, :right, :size
229
+
230
+ def initialize(key = nil, value = nil, size = 0)
231
+ @key = key
232
+ @value = value
233
+ @left = nil
234
+ @right = nil
235
+ @size = size
236
+ end
237
+ end
238
+ end
239
+ end
240
+ end
@@ -5,6 +5,7 @@ module Algorithmable
5
5
  autoload :LinkedList, 'algorithmable/data_structs/linked_list'
6
6
  autoload :Queue, 'algorithmable/data_structs/queue'
7
7
  autoload :Stack, 'algorithmable/data_structs/stack'
8
+ autoload :OrderedSymbolTable, 'algorithmable/data_structs/ordered_symbol_table'
8
9
 
9
10
  def new_bag
10
11
  Bag.new
@@ -21,5 +22,9 @@ module Algorithmable
21
22
  def new_lifo_queue
22
23
  Stack.new
23
24
  end
25
+
26
+ def new_ordered_symbol_table(key_type, value_type)
27
+ OrderedSymbolTable.new(key_type, value_type)
28
+ end
24
29
  end
25
30
  end
@@ -6,15 +6,17 @@ module Algorithmable
6
6
  end
7
7
 
8
8
  def lookup(element, collection)
9
+ return if element.nil?
9
10
  traverse element, collection, 0, collection.length - 1
10
11
  end
11
12
 
12
13
  def traverse(element, collection, low, high)
13
14
  while low <= high
14
15
  mid = low + (high - low) / 2
15
- if element < collection[mid]
16
+ value_at = collection[mid]
17
+ if element < value_at
16
18
  high = mid.pred
17
- elsif element > collection[mid]
19
+ elsif element > value_at
18
20
  low = mid.next
19
21
  else
20
22
  return mid
@@ -4,7 +4,7 @@ module Algorithmable
4
4
 
5
5
  class << self
6
6
  def binary(element, collection)
7
- Binary.index_of(element, collection)
7
+ Binary.lookup(element, collection)
8
8
  end
9
9
  end
10
10
  end
@@ -1,3 +1,3 @@
1
1
  module Algorithmable
2
- VERSION = '0.8.0'
2
+ VERSION = '0.9.0'
3
3
  end
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.8.0
4
+ version: 0.9.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-08 00:00:00.000000000 Z
11
+ date: 2016-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -144,6 +144,7 @@ files:
144
144
  - lib/algorithmable/data_structs/bag.rb
145
145
  - lib/algorithmable/data_structs/deque.rb
146
146
  - lib/algorithmable/data_structs/linked_list.rb
147
+ - lib/algorithmable/data_structs/ordered_symbol_table.rb
147
148
  - lib/algorithmable/data_structs/queue.rb
148
149
  - lib/algorithmable/data_structs/stack.rb
149
150
  - lib/algorithmable/errors.rb