-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.go
69 lines (67 loc) · 1.63 KB
/
search.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package process
type BoundsStruct interface {
GetBounds() [2]int
}
// binary search index given `Bound [2]int`
func Search(list []BoundsStruct, pos int) []int {
listLen := len(list)
if listLen == 0 {
return []int{-1, -1}
}
i := (listLen - 1) / 2
step := i
halfStep := func() {
step /= 2
if step == 0 {
step = 1
}
}
// 1. index between one bounds start & end
// or
// 2.between ( last end and current start ) or ( current end and next start )
for {
halfStep()
v := list[i]
vBound := v.GetBounds()
// between bounds
// or, width is 0 and index is the same
if vBound[0] <= pos && vBound[1] > pos {
return []int{i}
} else {
// smaller than start
if pos < vBound[0] {
if i > 0 {
// not the first one
prev := list[i-1]
if prev.GetBounds()[1] <= pos {
// i bigger than prev end and i smaller than current start means circumstance 2
return []int{i - 1, i}
} else {
// i smaller than prev end means still space to go left
i -= step
}
} else {
// first one and i smaller than first start means circumstance 2
return []int{-1, i}
}
} else if pos >= vBound[1] {
// bigger than end
if i < listLen-1 {
// not the last one
next := list[i+1]
if pos < next.GetBounds()[0] {
// i bigger than current end and smaller than next start means circumstance 2
return []int{i, i + 1}
} else {
// i bigger or equal to next start means still space to go right
i += step
}
} else {
// last one and i bigger than end means circumstance 2
// return []int{i, i + 1}
return []int{i, -1}
}
}
}
}
}