11#!/usr/bin/env ruby
2+ # frozen_string_literal: true
23
34module IntervalTree
4-
55 class Tree
66 def initialize ( ranges , &range_factory )
7- range_factory = lambda { | l , r | ( l ... r + 1 ) } unless block_given?
7+ range_factory = -> ( l , r ) { ( l ...r + 1 ) } unless block_given?
88 ranges_excl = ensure_exclusive_end ( [ ranges ] . flatten , range_factory )
99 @top_node = divide_intervals ( ranges_excl )
1010 end
1111 attr_reader :top_node
1212
1313 def divide_intervals ( intervals )
1414 return nil if intervals . empty?
15+
1516 x_center = center ( intervals )
16- s_center = Array . new
17- s_left = Array . new
18- s_right = Array . new
17+ s_center = [ ]
18+ s_left = [ ]
19+ s_right = [ ]
1920
2021 intervals . each do |k |
21- case
22- when k . end . to_r < x_center
22+ if k . end . to_r < x_center
2323 s_left << k
24- when k . begin . to_r > x_center
24+ elsif k . begin . to_r > x_center
2525 s_right << k
2626 else
2727 s_center << k
2828 end
2929 end
3030
3131 s_center . sort_by! { |x | [ x . begin , x . end ] }
32-
32+
3333 Node . new ( x_center , s_center ,
3434 divide_intervals ( s_left ) , divide_intervals ( s_right ) )
3535 end
3636
3737 # Search by range or point
38- DEFAULT_OPTIONS = { unique : true }
38+ DEFAULT_OPTIONS = { unique : true } . freeze
3939 def search ( query , options = { } )
4040 options = DEFAULT_OPTIONS . merge ( options )
4141
@@ -45,9 +45,9 @@ def search(query, options = {})
4545 result = top_node . search ( query )
4646 options [ :unique ] ? result . uniq! : result
4747 else
48- result = point_search ( self . top_node , query , [ ] , options [ :unique ] )
48+ result = point_search ( top_node , query , [ ] , options [ :unique ] )
4949 end
50- result
50+ result
5151 end
5252
5353 def ==( other )
@@ -58,10 +58,9 @@ def ==(other)
5858
5959 def ensure_exclusive_end ( ranges , range_factory )
6060 ranges . map do |range |
61- case
62- when !range . respond_to? ( :exclude_end? )
61+ if !range . respond_to? ( :exclude_end? )
6362 range
64- when range . exclude_end?
63+ elsif range . exclude_end?
6564 range
6665 else
6766 range_factory . call ( range . begin , range . end )
@@ -88,13 +87,14 @@ def point_search(node, point, result, unique)
8887
8988 node . s_center . each do |k |
9089 break if k . begin > point
90+
9191 result << k if point < k . end
9292 end
93-
94- if node_left_node && ( point_r < node_x_center )
93+
94+ if node_left_node && ( point_r < node_x_center )
9595 stack << node_left_node
9696
97- elsif node_right_node && ( point_r >= node_x_center )
97+ elsif node_right_node && ( point_r >= node_x_center )
9898 stack << node_right_node
9999 end
100100
@@ -105,7 +105,7 @@ def point_search(node, point, result, unique)
105105 result
106106 end
107107 end
108- end # class Tree
108+ end
109109
110110 class Node
111111 def initialize ( x_center , s_center , left_node , right_node )
@@ -118,9 +118,9 @@ def initialize(x_center, s_center, left_node, right_node)
118118
119119 def ==( other )
120120 x_center == other . x_center &&
121- s_center == other . s_center &&
122- left_node == other . left_node &&
123- right_node == other . right_node
121+ s_center == other . s_center &&
122+ left_node == other . left_node &&
123+ right_node == other . right_node
124124 end
125125
126126 # Search by range only
@@ -149,26 +149,26 @@ def search_s_center(query)
149149 next unless
150150 (
151151 # k is entirely contained within the query
152- ( k_begin_gte_q_begin ) &&
153- ( k_end_lte_q_end )
152+ k_begin_gte_q_begin &&
153+ k_end_lte_q_end
154154 ) || (
155155 # k's start overlaps with the query
156- ( k_begin_gte_q_begin ) &&
156+ k_begin_gte_q_begin &&
157157 ( k_begin < query_end )
158158 ) || (
159159 # k's end overlaps with the query
160160 ( k_end > query_begin ) &&
161- ( k_end_lte_q_end )
161+ k_end_lte_q_end
162162 ) || (
163163 # k is bigger than the query
164164 ( k_begin < query_begin ) &&
165165 ( k_end > query_end )
166166 )
167+
167168 result << k
168169 end
169170
170171 result
171172 end
172- end # class Node
173-
174- end # module IntervalTree
173+ end
174+ end
0 commit comments