collection_utils 1.0.0 → 2.0.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.
@@ -22,7 +22,7 @@ module CollectionUtils
22
22
  # @example Add element in queue
23
23
  # queue = CollectionUtils::Queue.new()
24
24
  # queue.enqueue(1)
25
- # queue.enqueue([1,3,4,])
25
+ # queue.enqueue([1,3,4])
26
26
  def enqueue(element)
27
27
  @queue << element
28
28
  end
@@ -33,8 +33,8 @@ module CollectionUtils
33
33
  # @example delete element from queue
34
34
  # queue = CollectionUtils::Queue.new()
35
35
  # queue.enqueue(1)
36
- # queue.enqueue([1,3,4,])
37
- # element = queue.dequeue #element = 1
36
+ # queue.enqueue([1,3,4])
37
+ # element = queue.dequeue #element = 1, queue = [[1,3,4]]
38
38
  def dequeue
39
39
  element = @queue.first
40
40
  @queue = @queue.slice(1..-1)
@@ -43,21 +43,41 @@ module CollectionUtils
43
43
 
44
44
 
45
45
  # @return element that has been recently added
46
+ # @example return front element from queue
47
+ # queue = CollectionUtils::Queue.new()
48
+ # queue.enqueue(1)
49
+ # queue.enqueue([1,3,4])
50
+ # element = queue.front #element = 1, queue = [1,[1,3,4]]
46
51
  def front
47
52
  return @queue.first
48
53
  end
49
54
 
50
55
  # @return element that will be dequeued next
56
+ # @example return rear element from queue
57
+ # queue = CollectionUtils::Queue.new()
58
+ # queue.enqueue(1)
59
+ # queue.enqueue([1,3,4])
60
+ # element = queue.rear #element = [1,3,4], queue = [1,[1,3,4]]
51
61
  def rear
52
62
  return @queue.last
53
63
  end
54
64
 
55
65
  # @return [Boolean] which tells queue's emptiness
66
+ # @example return emptiness of queue
67
+ # queue = CollectionUtils::Queue.new()
68
+ # queue.enqueue(1)
69
+ # queue.enqueue([1,3,4])
70
+ # queue.is_empty? #false
56
71
  def is_empty?
57
72
  return @queue.size == 0
58
73
  end
59
74
 
60
75
  # @return [Integer] size of queue
76
+ # @example return size of queue
77
+ # queue = CollectionUtils::Queue.new()
78
+ # queue.enqueue(1)
79
+ # queue.enqueue([1,3,4])
80
+ # size = queue.size #size = 2
61
81
  def size
62
82
  return @queue.size
63
83
  end
@@ -0,0 +1,144 @@
1
+ module CollectionUtils
2
+ class Set
3
+ private
4
+ attr_accessor :set
5
+
6
+ def get_key_value(val)
7
+ instance_variables = val.instance_variables
8
+ if instance_variables.empty?
9
+ return val.hash, val
10
+ end
11
+ variables = instance_variables.inject(Hash.new(0)) {|h,e|
12
+ h[e] = val.instance_variable_get(e);h
13
+ }
14
+ return variables.hash, val
15
+ end
16
+
17
+ public
18
+ def initialize(values = [])
19
+ @set = {}
20
+ values.each do |value|
21
+ insert(value)
22
+ end
23
+ end
24
+
25
+ # Insert an element into set. This is done in O(1) operations
26
+ #
27
+ # @param val element that needs to be added
28
+ # @return [Boolean] true if element is added, false if element is already present
29
+ # @example Add element into set
30
+ # => set = CollectionUtils::Set.new([1,2,3,4])
31
+ # => set.size #4
32
+ # => set.insert(5)
33
+ # => set.size #5
34
+ # => set.insert(4)
35
+ # => set.size #5
36
+ def insert(val)
37
+ key, value = get_key_value(val)
38
+ @set[key] = value; return true if @set[key].nil?
39
+ return false
40
+ end
41
+
42
+ # checks whether an element is present or not.
43
+ # This is done in O(1) operations
44
+ # @param val which has to be checked whether in set or not
45
+ # @return [Boolean] true if element is present, false if element is already present
46
+ # @example check an element in set
47
+ # => set = CollectionUtils::Set.new([1,2,3,4])
48
+ # => set.check(4) #true
49
+ # => set.check(5) #false
50
+ def check(val)
51
+ key, value = get_key_value(val)
52
+ return !@set[key].nil?
53
+ end
54
+
55
+ # deletes an element from the set.
56
+ # This is done in O(1) operations
57
+ # @param val which has to be deleted
58
+ # @example check an element in set
59
+ # => set = CollectionUtils::Set.new([1,2,3,4])
60
+ # => set.delete(4) #set = [1,2,3]
61
+ # => set.delete(5) #set = [1,2,3]
62
+ def delete(val)
63
+ key, value = get_key_value(val)
64
+ @set.delete(key)
65
+ end
66
+
67
+
68
+ # Get a random element from the set.
69
+ #
70
+ # @return a random element from set.
71
+ # @example get an element from set
72
+ # => set = CollectionUtils::Set.new([1,2,3,4])
73
+ # => set.get # 3
74
+ # => set.get # 4
75
+ # => set.get # 3
76
+ def get
77
+ @set.values.sample
78
+ end
79
+
80
+ # Get all the values from a set.
81
+ #
82
+ # @return all the elements from the set.
83
+ # @example get all element from set
84
+ # => set = CollectionUtils::Set.new([1,2,3,4])
85
+ # => set.get_values #[1,2,3,4]
86
+ def get_values
87
+ @set.values
88
+ end
89
+
90
+ # @return [Integer] size of the
91
+ # @example return size of set
92
+ # => set = CollectionUtils::Set.new([1,2,3,4])
93
+ # => set.size #4
94
+ def size
95
+ @set.keys.size
96
+ end
97
+
98
+ # Returns whether the set is empty. This is just a syntax_sugar
99
+ # for size == 0
100
+ # @return [Boolean] set's emptiness
101
+ def is_empty?
102
+ size == 0
103
+ end
104
+
105
+ # Intersection of two sets and return the intersected set
106
+ #
107
+ # @param [Set] set with which Intersection of the current set needs to be taken
108
+ # @return [Set] intersected set
109
+ # @example Intesect two sets and return it.
110
+ # => set1 = CollectionUtils::Set.new([1,2,3,4])
111
+ # => set2 = CollectionUtils::Set.new([2,3,4,5])
112
+ # => set3 = set1 & set2 #[2,3,4]
113
+ def &(set)
114
+ new_set = Set.new(get_values & set.get_values)
115
+ return new_set
116
+ end
117
+
118
+ # Union of two sets and return the united set
119
+ #
120
+ # @param [Set] set with which Union of the current set needs to be taken
121
+ # @return [Set] united set
122
+ # @example Union two sets and return it.
123
+ # => set1 = CollectionUtils::Set.new([1,2,3,4])
124
+ # => set2 = CollectionUtils::Set.new([2,3,4,5])
125
+ # => set3 = set1 + set2 #[1,2,3,4,5]
126
+ def +(set)
127
+ new_set = Set.new(get_values + set.get_values)
128
+ return new_set
129
+ end
130
+
131
+ # Difference of two sets and return the subtracted set
132
+ #
133
+ # @param [Set] set with which Difference of the current set needs to be taken
134
+ # @return [Set] subtracted set
135
+ # @example subtracted two sets and return it.
136
+ # => set1 = CollectionUtils::Set.new([1,2,3,4])
137
+ # => set2 = CollectionUtils::Set.new([2,3,4,5])
138
+ # => set3 = set1 - set2 #[1]
139
+ def -(set)
140
+ new_set = Set.new(get_values - set.get_values)
141
+ end
142
+
143
+ end
144
+ end
@@ -18,7 +18,7 @@ module CollectionUtils
18
18
  #
19
19
  # @example Create a stack [1,2,3,4,5] and remove 5 using pop
20
20
  # stack = CollectionUtils::Stack.new([1,2,3,4,5])
21
- # top_element = stack.pop()
21
+ # top_element = stack.pop() # top_element = 5, stack = [1,2,3,4]
22
22
  def pop
23
23
  return @stack.pop
24
24
  end
@@ -36,6 +36,9 @@ module CollectionUtils
36
36
  end
37
37
 
38
38
  # @return [Boolean] stack's emptiness
39
+ # @example Create a stack [1,2,3,4,5] and add check emptiness.
40
+ # stack = CollectionUtils::Stack.new([1,2,3,4,5])
41
+ # stack.is_empty? # false
39
42
  def is_empty?
40
43
  return @stack.size == 0
41
44
  end
@@ -46,12 +49,15 @@ module CollectionUtils
46
49
  #
47
50
  # @example Create a stack [1,2,3,4,5] and get 5 using peek
48
51
  # stack = CollectionUtils::Stack.new([1,2,3,4,5])
49
- # top_element = stack.peek # top_element = 5
52
+ # top_element = stack.peek # top_element = 5, stack = [1,2,3,4,5]
50
53
  def peek
51
54
  return @stack.last
52
55
  end
53
56
 
54
57
  # @return [Integer] size of stack
58
+ # @example Create a stack [1,2,3,4,5] and check size.
59
+ # stack = CollectionUtils::Stack.new([1,2,3,4,5])
60
+ # stack.size # 5
55
61
  def size
56
62
  return @stack.size
57
63
  end
@@ -3,65 +3,221 @@ module CollectionUtils
3
3
  module TreeUtils
4
4
  class BST < CollectionUtils::Tree
5
5
  private
6
- attr_accessor :bst, :height
7
6
 
8
- public
9
- def initialize(arr = [])
10
- @heap = []
11
- @height = 0
12
- arr.each do |element|
13
- insert(element, root)
7
+ def delete_node(element, node)
8
+ if element == node.val
9
+ @size -= 1
10
+ @leaf_set.delete(node)
11
+ # if the node is leaf then add the parent to leaf set if
12
+ # parent.is_leaf? and assign the left or right to nil based on
13
+ # where the node is attached to the parent.
14
+ if node.is_leaf?
15
+ parent = node.parent
16
+ @leaf_set.delete(parent)
17
+ parent.left == node ? parent.left = nil : parent.right = nil
18
+ @leaf_set.insert(parent) if parent.is_leaf?
19
+ return
20
+ # if the right child is leaf for the node then exchange the value of
21
+ # right child and node and delete the right child.
22
+ elsif node.right.is_leaf?
23
+ node.val = node.right.val
24
+ node.right = nil
25
+ @leaf_set.insert(node) if node.is_leaf?
26
+ return
27
+ # if the left child is leaf for the node then exchange the value of
28
+ # left child and node and delete the left child.
29
+ elsif node.left.is_leaf?
30
+ node.val = node.left.val
31
+ node.left = nil
32
+ @leaf_set.insert(node) if node.is_leaf?
33
+ return
34
+ else
35
+ # find the smallest child on the right side and exchange the
36
+ # value with the node. Balance the tree accordingly.
37
+ smallest = find_smallest(node.right)
38
+ if smallest.is_leaf?
39
+ @leaf_set.delete(smallest)
40
+ node.val = smallest.val
41
+ @leaf_set.insert(node) if node.is_leaf?
42
+ else
43
+ if smallest == smallest.parent.left
44
+ smallest.parent.left = smallest.right
45
+ node.val = smallest.val
46
+ smallest = nil
47
+ else
48
+ smallest.parent.right = smallest.right
49
+ node.val = smallest.val
50
+ smallest = nil
51
+ end
52
+ end
53
+
54
+ end
55
+ elsif element > node.val
56
+ delete_node(element, node.right)
57
+ else
58
+ delete_node(element, node.left)
14
59
  end
15
60
  end
16
61
 
17
- def insert(element, node)
18
- if !is_empty? && node == root
19
- @height = 1
62
+ def find_smallest(node)
63
+ smallest = node.val
64
+ left = node.left
65
+ while left != nil do
66
+ smallest = left.val
67
+ left = left.left
20
68
  end
21
- if is_empty?
22
- @height = 1
23
- @heap << {element: element, index: 0}
24
- return
69
+ return smallest
70
+ end
71
+
72
+ def find_largest(node)
73
+ largest = node.val
74
+ right = node.right
75
+ while right != nil do
76
+ largest = right.val
77
+ right = right.right
25
78
  end
26
- @height += 1
27
- if element > node[:element]
28
- right = right(node[:index])
29
- if right.nil?
30
- parent = node[:index]
31
- right_in = right_index(parent)
32
- value = {element: element, index: right_in}
33
- assign_right(parent, value)
79
+ return largest
80
+ end
81
+
82
+ def insert_node(node, parent_node)
83
+ if node.val >= parent_node.val
84
+ if parent_node.right.nil?
85
+ @leaf_set.delete(parent_node)
86
+ parent_node.right = node
87
+ node.level = parent_node.level + 1
88
+ @level = node.level if node.level > @level
89
+ @leaf_set.insert(node) if node.is_leaf?
34
90
  return
35
91
  else
36
- insert(element, right)
37
- return
92
+ insert_node(node, parent_node.right)
38
93
  end
39
94
  else
40
- left = left(node[:index])
41
- if left.nil?
42
- parent = node[:index]
43
- left_in = left_index(parent)
44
- value = {element: element, index: left_in}
45
- assign_left(parent, value)
95
+ if parent_node.left.nil?
96
+ @leaf_set.delete(parent_node)
97
+ parent_node.left = node
98
+ node.level = parent_node.level + 1
99
+ @level = node.level if node.level > @level
100
+ @leaf_set.insert(node) if node.is_leaf?
46
101
  return
47
102
  else
48
- insert(element, left)
49
- return
103
+ insert_node(node, parent_node.left)
50
104
  end
51
105
  end
106
+ end
107
+
108
+ public
109
+ def initialize(arr = [])
110
+ @size = 0
111
+ @root = nil
112
+ @incomplete_set = CollectionUtils::Set.new()
113
+ @leaf_set = CollectionUtils::Set.new()
114
+ arr.each do |element|
115
+ insert(element)
116
+ end
117
+ end
118
+
119
+ # Insert would insert the next element in BST according to
120
+ # BST properties that is if element added is less than the parent_node
121
+ # then element will be at left side of the node else will be on the right
122
+ # side of the node. This operation is in O(logn)
123
+ # @param element Element which needs to be added to BST
124
+ # @example if tree has values [5,2,3,4]
125
+ # => @bst = CollectionUtils::TreeUtils::BST.new([5,2,3,4])
126
+ # => # BST would look like this
127
+ # => # 5
128
+ # => # /
129
+ # => # 2
130
+ # => # \
131
+ # => # 3
132
+ # => # \
133
+ # => # 4
134
+ # => @bst.insert(6)
135
+ # => # Now BST would look like this
136
+ # => # 5
137
+ # => # / \
138
+ # => # 2 6
139
+ # => # \
140
+ # => # 3
141
+ # => # \
142
+ # => # 4
52
143
 
144
+ def insert(element)
145
+ node = Node.new(element)
146
+ if is_empty?
147
+ @root = node
148
+ @root.level = 1
149
+ @level = 1
150
+ @size += 1
151
+ @leaf_set.insert(node)
152
+ return
153
+ end
154
+ insert_node(node, @root)
53
155
  end
54
156
 
55
- def get_min
56
- return root[:element]
157
+ # Delete would delete the element in BST and balance the BST accordingly.
158
+ # The delete option uses the BST property that is every node has lesser value
159
+ # on the left side and larger value lies on the right side.
160
+ # This operation is in O(logn)
161
+ # @param element Element which needs to be deleted from BST
162
+ # @example if tree has values [5,2,3,4,6]
163
+ # => @bst = CollectionUtils::TreeUtils::BST.new([5,2,3,4])
164
+ # => # BST would look like this
165
+ # => # 5
166
+ # => # / \
167
+ # => # 2 6
168
+ # => # \
169
+ # => # 3
170
+ # => # \
171
+ # => # 4
172
+ # => @bst.insert(5)
173
+ # => # Now BST would look like this
174
+ # => # 6
175
+ # => # /
176
+ # => # 2
177
+ # => # \
178
+ # => # 3
179
+ # => # \
180
+ # => # 4
181
+ def delete(element)
182
+ delete_node(element, @root)
57
183
  end
58
184
 
59
- def is_empty?
60
- return @heap.empty?
185
+ # Leftmost value will be the smallest value returned using this function
186
+ # This operation is in O(logn)
187
+ # @return element which is smallest in the BST
188
+ # @example if tree has values [5,2,3,4,6]
189
+ # => @bst = CollectionUtils::TreeUtils::BST.new([5,2,3,4])
190
+ # => # BST would look like this
191
+ # => # 5
192
+ # => # / \
193
+ # => # 2 6
194
+ # => # \
195
+ # => # 3
196
+ # => # \
197
+ # => # 4
198
+ # => value = @bst.smallest
199
+ # => value == 2
200
+ def smallest
201
+ find_smallest(@root)
61
202
  end
62
203
 
63
- def get_height
64
- @height
204
+ # Rightmost value will be the largest value returned using this function
205
+ # This operation is in O(logn)
206
+ # @return element which is largest in the BST
207
+ # @example if tree has values [5,2,3,4,6]
208
+ # => @bst = CollectionUtils::TreeUtils::BST.new([5,2,3,4])
209
+ # => # BST would look like this
210
+ # => # 5
211
+ # => # / \
212
+ # => # 2 6
213
+ # => # \
214
+ # => # 3
215
+ # => # \
216
+ # => # 4
217
+ # => value = @bst.largest
218
+ # => value == 6
219
+ def largest
220
+ find_largest(@root)
65
221
  end
66
222
 
67
223
  end