rb_binary_heap 2.1

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/rb_binary_heap.rb +142 -0
  3. metadata +43 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2a3883375b2b15e01fdb4876a3e19143424ce70397ffb588f009cdc3fd94bfee
4
+ data.tar.gz: 76e7611f011248d9e6cebe35d6bce18e416ec2df52d0efe33a29269598cbbbf7
5
+ SHA512:
6
+ metadata.gz: 2900b3619db8f8a1b5a109b6cb882c1b7f51bb963f8502a547711edc598fffaa7628f4f1b26e11b808747ab2ab1509127780606947f1a253687776589b980a46
7
+ data.tar.gz: '04193409cf464213dae17f7e3b9fa6027887a7b6c1ebb59ca065ed71db79f8576b1a8ebe69fc994e94bc97341905da020eb7fae72918d5ec1cfb5a7f4b51e02f'
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BinaryHeap
4
+ include Enumerable
5
+
6
+ def initialize(array = [], type: nil, compare_attribute: nil, &block)
7
+ @array = array
8
+
9
+ comparison_method_name = :compare
10
+
11
+ if block_given?
12
+ if type || compare_attribute
13
+ raise 'Heap: :type and :compare_attribute should not be defined if the block is given'
14
+ end
15
+
16
+ define_singleton_method(comparison_method_name) do |a, b|
17
+ block.call a, b
18
+ end
19
+ else
20
+ type = :min if type.nil?
21
+
22
+ op = heap_type_to_comparison_operator type
23
+
24
+ if compare_attribute.nil?
25
+ define_singleton_method(comparison_method_name) do |a, b|
26
+ a.send(op, b)
27
+ end
28
+ else
29
+ define_singleton_method(comparison_method_name) do |a, b|
30
+ a_value = a.send(compare_attribute)
31
+ b_value = b.send(compare_attribute)
32
+ a_value.send(op, b_value)
33
+ end
34
+ end
35
+ end
36
+
37
+ heapify
38
+ end
39
+
40
+ def top
41
+ raise "Heap: Can't get the top element, heap is empty" if @array.empty?
42
+ @array.first
43
+ end
44
+
45
+ def push(value)
46
+ @array.push value
47
+ sift_up_from_last
48
+ self
49
+ end
50
+
51
+ def pop
52
+ raise "Heap: Can't pop, heap is empty" if @array.empty?
53
+ return @array.pop if @array.size == 1
54
+
55
+ result = @array.first
56
+ last_element = @array.pop
57
+ @array[0] = last_element
58
+
59
+ sift_down_from_first
60
+ result
61
+ end
62
+
63
+ def not_empty?
64
+ !empty?
65
+ end
66
+
67
+ def empty?
68
+ @array.empty?
69
+ end
70
+
71
+ def each
72
+ yield pop while not_empty?
73
+ end
74
+
75
+ def size
76
+ @array.size
77
+ end
78
+
79
+ private
80
+
81
+ def heapify
82
+ i = @array.size / 2
83
+ while i >= 0
84
+ sift_down_from i
85
+ i -= 1
86
+ end
87
+ end
88
+
89
+ def sift_up_from_last
90
+ sift_up_from @array.size - 1
91
+ end
92
+
93
+ def sift_down_from_first
94
+ sift_down_from 0
95
+ end
96
+
97
+ def sift_up_from(i)
98
+ while i.positive?
99
+ parent = (i - 1) / 2
100
+
101
+ break if compare(@array[parent], @array[i])
102
+
103
+ swap i, parent
104
+
105
+ i = parent
106
+ end
107
+ end
108
+
109
+ def sift_down_from(i)
110
+ while (left = 2 * i + 1) < @array.size
111
+ largest = i
112
+
113
+ largest = left if !compare(@array[largest], @array[left])
114
+
115
+ right = 2 * i + 2
116
+
117
+ if right < @array.size && !compare(@array[largest], @array[right])
118
+ largest = right
119
+ end
120
+
121
+ break if largest == i
122
+
123
+ swap i, largest
124
+
125
+ i = largest
126
+ end
127
+ end
128
+
129
+ def swap(i, j)
130
+ @array[i], @array[j] = @array[j], @array[i]
131
+ end
132
+
133
+ def heap_type_to_comparison_operator(type)
134
+ case type
135
+ when :min then :<
136
+ when :max then :>
137
+ else
138
+ raise 'Heap: :type should be either :min or :max'
139
+ end
140
+ end
141
+ end
142
+
metadata ADDED
@@ -0,0 +1,43 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rb_binary_heap
3
+ version: !ruby/object:Gem::Version
4
+ version: '2.1'
5
+ platform: ruby
6
+ authors:
7
+ - metacircu1ar
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-01-20 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Implementation of a binary heap in Ruby. See github for usage examples.
14
+ email: ''
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/rb_binary_heap.rb
20
+ homepage: https://github.com/metacircu1ar/rb_binary_heap
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubygems_version: 3.4.1
40
+ signing_key:
41
+ specification_version: 4
42
+ summary: Binary heap
43
+ test_files: []