-
Notifications
You must be signed in to change notification settings - Fork 0
/
NumberOfDiscIntersections.go
61 lines (53 loc) · 1.08 KB
/
NumberOfDiscIntersections.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
package codility
import (
"sort"
)
// sort by the begin points
type Disc struct {
Begin, End int
}
type SortableDiscs []Disc
func (d SortableDiscs) Len() int {
return len(d)
}
func (d SortableDiscs) Less(i, j int) bool {
return d[i].Begin < d[j].Begin
}
func (d SortableDiscs) Swap(i, j int) {
d[i], d[j] = d[j], d[i]
}
func NewDiscs(A []int) []Disc {
discs := make([]Disc, len(A))
for i := range discs {
discs[i].Begin = i - A[i]
discs[i].End = i + A[i]
}
return discs
}
// https://codility.com/programmers/task/number_of_disc_intersections/
func NumberOfDiscIntersections(A []int) int {
discs := SortableDiscs(NewDiscs(A))
sort.Sort(discs)
pairs := 0
for i := 0; i < len(discs)-1; i++ {
// Binary search for the end
for left, right := i+1, len(discs)-1; ; {
if discs[i].End >= discs[right].Begin {
pairs += right - i
if pairs > 10000000 {
return -1
}
break
}
mid := (left + right) / 2
if discs[i].End >= discs[mid].Begin && mid != left {
left = mid
} else if mid != right {
right = mid
} else {
break
}
}
}
return pairs
}