75 lines
2.0 KiB
Go
75 lines
2.0 KiB
Go
package intervals
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
)
|
|
|
|
func (intvls *intervals) HasOverlapped() bool {
|
|
intvls.Overlapped()
|
|
if intvls.OverlappedList != nil && len(intvls.OverlappedList) > 0 {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (intvls *intervals) Overlapped() []*Interval {
|
|
if intvls.OverlappedList == nil {
|
|
intvls.OverlappedList = intvls.calculateOverlapped()
|
|
}
|
|
return intvls.OverlappedList
|
|
}
|
|
|
|
func (intvls *intervals) calculateOverlapped() []*Interval {
|
|
list := []*Interval{}
|
|
if len(intvls.Intervals) == 0 {
|
|
return list
|
|
}
|
|
|
|
// sort intervals (if necessary)
|
|
intvls.Sort()
|
|
|
|
lastMinLow := math.MaxInt64
|
|
lastMaxHigh := math.MinInt64
|
|
firstInitDone := false
|
|
for _, intvl := range intvls.Intervals {
|
|
// convert if necessary exclusive low/high values into inclusive ones
|
|
low, high, err := intvls.getInclusives(intvl.Low, intvl.High)
|
|
if err != nil {
|
|
fmt.Printf("calculateOverlapped - unable to get inclusives: %v", err)
|
|
continue
|
|
}
|
|
|
|
// for the first iteration make no sense those operations
|
|
if firstInitDone {
|
|
// check if the front or back side of the current segment overlaps with the previous one
|
|
lowInBetween := isLowInBetweenInclusive(lastMinLow, lastMaxHigh, low, high)
|
|
highInBetween := isHighInBetweenInclusive(lastMinLow, lastMaxHigh, low, high)
|
|
if lowInBetween || highInBetween {
|
|
// extract which part is overlapped, create a new interval and add it to the list
|
|
biggestLow := max(low, lastMinLow)
|
|
smallestHigh := min(high, lastMaxHigh)
|
|
list = append(list, &Interval{Low: biggestLow, High: smallestHigh})
|
|
}
|
|
}
|
|
// update control variables (if necessary)
|
|
if low < lastMinLow {
|
|
lastMinLow = low
|
|
}
|
|
if high > lastMaxHigh {
|
|
lastMaxHigh = high
|
|
}
|
|
firstInitDone = true
|
|
}
|
|
return list
|
|
}
|
|
|
|
func (intvls *intervals) valueIsOverlapping(value int, overlapped []*Interval) bool {
|
|
for _, ovrlp := range overlapped {
|
|
if inBetween(value, ovrlp.Low, ovrlp.High, intvls.LowInclusive, intvls.HighInclusive) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|