algorithmable 0.8.0 → 0.9.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.
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