Skip to content

Commit ae1026e

Browse files
committed
task2 solution
1 parent a3c64e1 commit ae1026e

File tree

1 file changed

+62
-44
lines changed

1 file changed

+62
-44
lines changed

week4/priority-queues/task2/solution.rb

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,13 @@ def initialize(values = [])
55
@arr = values.dup
66

77
(arr.size / 2 - 1).downto(0).each do |i|
8-
heapify!(i)
8+
heapify_down(i)
99
end
1010
end
1111

1212
def push(value)
13-
i = arr.size
1413
arr << value
15-
parent_i = (i - 1) / 2
16-
17-
while i > 0 && arr[parent_i] < arr[i]
18-
swap(i, parent_i)
19-
i = parent_i
20-
parent_i = (i - 1) / 2
21-
end
14+
heapify_up(arr.size - 1)
2215
end
2316

2417
def max
@@ -30,7 +23,7 @@ def pop
3023
last = arr.pop
3124
unless arr.empty?
3225
arr[0] = last
33-
heapify!(0)
26+
heapify_down(0)
3427
end
3528
value
3629
end
@@ -45,63 +38,88 @@ def sample
4538

4639
# logarithmic time
4740
def delRandom
48-
i = rand(arr.size)
49-
x = arr[i]
41+
index = rand(arr.size)
42+
x = arr[index]
5043

51-
swap(i, arr.size - 1)
44+
swap(index, arr.size - 1)
5245
arr.pop
5346

54-
(0...arr.size).each do |k|
55-
heapify!(k)
56-
end
57-
(0...arr.size).each do |k|
58-
heapify!(k)
59-
end
60-
(0...arr.size).each do |k|
61-
heapify!(k)
47+
unless index == arr.size
48+
if index == 0 || arr[index] <= arr[parent_index(index)]
49+
heapify_down(index)
50+
else
51+
heapify_up(index)
52+
end
6253
end
6354

6455
x
6556
end
6657

6758
def valid_heap?
6859
return true if arr.empty?
69-
(0..(arr.size / 2 - 1)).each do |parent_idx|
70-
left_child_idx = 2 * parent_idx + 1
71-
right_child_idx = 2 * parent_idx + 2
72-
return false if left_child_idx < arr.size && arr[left_child_idx] > arr[parent_idx]
73-
return false if right_child_idx < arr.size && arr[right_child_idx] > arr[parent_idx]
60+
(0..(arr.size / 2 - 1)).each do |parent_i|
61+
left_i = left_index(parent_i)
62+
right_i = right_index(parent_i)
63+
return false if left_i < arr.size && arr[left_i] > arr[parent_i]
64+
return false if right_i < arr.size && arr[right_i] > arr[parent_i]
7465
end
7566
true
7667
end
7768

78-
private def heapify!(i)
79-
loop do
80-
left_child = 2 * i + 1
81-
right_child = 2 * i + 2
82-
largest_child = i
69+
private def heapify_up(index)
70+
parent_i = parent_index(index)
8371

84-
largest_child = left_child if left_child < arr.size && arr[left_child] > arr[largest_child]
85-
largest_child = right_child if right_child < arr.size && arr[right_child] > arr[largest_child]
72+
return if index == 0 || @arr[index] <= @arr[parent_i]
8673

87-
break if largest_child == i
74+
swap(index, parent_i)
75+
heapify_up(parent_i)
76+
end
8877

89-
swap(i, largest_child)
90-
i = largest_child
91-
end
78+
private def heapify_down(index)
79+
left_i = left_index(index)
80+
right_i = right_index(index)
81+
largest_child = index
82+
83+
largest_child = left_i if left_i < arr.size && arr[left_i] > arr[largest_child]
84+
largest_child = right_i if right_i < arr.size && arr[right_i] > arr[largest_child]
85+
86+
return if largest_child == index
87+
88+
swap(index, largest_child)
89+
heapify_down(largest_child)
90+
end
91+
92+
private def parent_index(index)
93+
(index - 1) / 2
94+
end
95+
96+
def left_index(index)
97+
2 * index + 1
98+
end
99+
100+
def right_index(index)
101+
2 * index + 2
92102
end
93103

94104
private def swap(i, j)
105+
return if i == j
95106
arr[i], arr[j] = arr[j], arr[i]
96107
end
97108
end
98109

99-
n = rand(3..9)
100-
a = Array.new(n) { rand(1..99) }.uniq
110+
100.times do
111+
n = rand(3..9)
112+
a = Array.new(n) { rand(1..99) }.uniq
113+
114+
h1 = Heap.new(a)
115+
x = h1.delRandom
116+
b = a - [x]
117+
h2 = Heap.new(b)
101118

102-
h1 = Heap.new(a)
103-
x = h1.delRandom
104-
b = a - [x]
105-
h2 = Heap.new(b)
119+
unless h1.arr.sort == h2.arr.sort && h1.valid_heap? && h2.valid_heap?
120+
puts "ERROR: h1 = #{h1.arr}, h2 = #{h2.arr} | #{h1.valid_heap?} #{h2.valid_heap?}"
121+
exit
122+
end
123+
end
106124

107-
p h1.arr.sort == h2.arr.sort && h1.valid_heap? && h2.valid_heap?
125+
puts "OK"

0 commit comments

Comments
 (0)