fixed gaps calculations
This commit is contained in:
parent
7255f129f5
commit
941fe9746a
@ -18,3 +18,10 @@ type ByLow []*Interval
|
|||||||
func (itvls ByLow) Len() int { return len(itvls) }
|
func (itvls ByLow) Len() int { return len(itvls) }
|
||||||
func (itvls ByLow) Swap(i, j int) { itvls[i], itvls[j] = itvls[j], itvls[i] }
|
func (itvls ByLow) Swap(i, j int) { itvls[i], itvls[j] = itvls[j], itvls[i] }
|
||||||
func (itvls ByLow) Less(i, j int) bool { return itvls[i].Low < itvls[j].Low }
|
func (itvls ByLow) Less(i, j int) bool { return itvls[i].Low < itvls[j].Low }
|
||||||
|
|
||||||
|
// ByHigh implements sort.Interface for []Interval based on the High field.
|
||||||
|
type ByHigh []*Interval
|
||||||
|
|
||||||
|
func (itvls ByHigh) Len() int { return len(itvls) }
|
||||||
|
func (itvls ByHigh) Swap(i, j int) { itvls[i], itvls[j] = itvls[j], itvls[i] }
|
||||||
|
func (itvls ByHigh) Less(i, j int) bool { return itvls[i].High > itvls[j].High }
|
||||||
|
59
intervals.go
59
intervals.go
@ -11,8 +11,8 @@ const (
|
|||||||
defaultMaxHigh = math.MaxInt64
|
defaultMaxHigh = math.MaxInt64
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Intervals is an interface to handle Interval structures discovering the existence of gaps or overlays
|
||||||
type Intervals interface {
|
type Intervals interface {
|
||||||
// Add appends a new interval
|
|
||||||
Add(itvl *Interval)
|
Add(itvl *Interval)
|
||||||
|
|
||||||
// Sort sorts the intervals list by the Low property (ascending)
|
// Sort sorts the intervals list by the Low property (ascending)
|
||||||
@ -31,6 +31,7 @@ type Intervals interface {
|
|||||||
Print() string
|
Print() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// intervals implements Intervals interface
|
||||||
type intervals struct {
|
type intervals struct {
|
||||||
Intervals []*Interval
|
Intervals []*Interval
|
||||||
MinLow int
|
MinLow int
|
||||||
@ -38,10 +39,12 @@ type intervals struct {
|
|||||||
Sorted bool
|
Sorted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewIntervalsDefault is a constructor that returns an instance of the Intervals interface with default values
|
||||||
func NewIntervalsDefault() Intervals {
|
func NewIntervalsDefault() Intervals {
|
||||||
return NewIntervals(defaultMinLow, defaultMaxHigh)
|
return NewIntervals(defaultMinLow, defaultMaxHigh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewIntervals is a constructor that returns an instance of the Intervals interface
|
||||||
func NewIntervals(minLow int, maxHigh int) Intervals {
|
func NewIntervals(minLow int, maxHigh int) Intervals {
|
||||||
return &intervals{
|
return &intervals{
|
||||||
MinLow: minLow,
|
MinLow: minLow,
|
||||||
@ -57,8 +60,13 @@ func (intvls *intervals) Add(itvl *Interval) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (intvls *intervals) FindIntervalsForValue(value int) []*Interval {
|
func (intvls *intervals) FindIntervalsForValue(value int) []*Interval {
|
||||||
|
intvls.Sort()
|
||||||
var matches []*Interval
|
var matches []*Interval
|
||||||
for _, intvl := range intvls.Intervals {
|
for _, intvl := range intvls.Intervals {
|
||||||
|
if intvl.Low > value {
|
||||||
|
// due to the intervals are sorted, we can confirm that we will not find more matches
|
||||||
|
break
|
||||||
|
}
|
||||||
if inBetweenInclusive(value, intvl.Low, intvl.High) {
|
if inBetweenInclusive(value, intvl.Low, intvl.High) {
|
||||||
matches = append(matches, intvl)
|
matches = append(matches, intvl)
|
||||||
}
|
}
|
||||||
@ -76,15 +84,18 @@ func (intvls *intervals) Sort() {
|
|||||||
func (intvls *intervals) Gaps() []*Interval {
|
func (intvls *intervals) Gaps() []*Interval {
|
||||||
intvls.Sort()
|
intvls.Sort()
|
||||||
gaps := []*Interval{}
|
gaps := []*Interval{}
|
||||||
lastHigh := intvls.MinLow
|
lastMaxHigh := intvls.MinLow
|
||||||
for _, intvl := range intvls.Intervals {
|
for _, intvl := range intvls.Intervals {
|
||||||
if intvl.Low > lastHigh {
|
if intvl.Low > lastMaxHigh {
|
||||||
gaps = append(gaps, &Interval{Low: lastHigh, High: intvl.Low - 1})
|
gaps = append(gaps, &Interval{Low: lastMaxHigh, High: intvl.Low - 1})
|
||||||
|
}
|
||||||
|
// lastHigh = intvl.High + 1
|
||||||
|
if intvl.High >= lastMaxHigh {
|
||||||
|
lastMaxHigh = intvl.High + 1
|
||||||
}
|
}
|
||||||
lastHigh = intvl.High + 1
|
|
||||||
}
|
}
|
||||||
if lastHigh < intvls.MaxHigh {
|
if lastMaxHigh < intvls.MaxHigh {
|
||||||
gaps = append(gaps, &Interval{Low: lastHigh, High: intvls.MaxHigh})
|
gaps = append(gaps, &Interval{Low: lastMaxHigh, High: intvls.MaxHigh})
|
||||||
}
|
}
|
||||||
return gaps
|
return gaps
|
||||||
}
|
}
|
||||||
@ -114,7 +125,7 @@ func (intvls *intervals) Overlapped() []*Interval {
|
|||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
func (intvls *intervals) isAnOverlap(value int, overlapped []*Interval) bool {
|
func (intvls *intervals) isOverlapping(value int, overlapped []*Interval) bool {
|
||||||
for _, ovrlp := range overlapped {
|
for _, ovrlp := range overlapped {
|
||||||
if inBetweenInclusive(value, ovrlp.Low, ovrlp.High) {
|
if inBetweenInclusive(value, ovrlp.Low, ovrlp.High) {
|
||||||
return true
|
return true
|
||||||
@ -130,7 +141,9 @@ func (intvls *intervals) Print() string {
|
|||||||
emptySymbol := "◌"
|
emptySymbol := "◌"
|
||||||
fullSymbol := "◎"
|
fullSymbol := "◎"
|
||||||
overlapSymbol := "●"
|
overlapSymbol := "●"
|
||||||
separator := "║"
|
leadingSymbol := "├"
|
||||||
|
trailingSymbol := "┤"
|
||||||
|
separator := "|"
|
||||||
|
|
||||||
introText := fmt.Sprintf("\n==================================\n SUMMARY (minLow=%d, maxHigh=%d)\n==================================", intvls.MinLow, intvls.MaxHigh)
|
introText := fmt.Sprintf("\n==================================\n SUMMARY (minLow=%d, maxHigh=%d)\n==================================", intvls.MinLow, intvls.MaxHigh)
|
||||||
legend := fmt.Sprintf("\n • Legend: %v (empty), %v (full), %v (overlap)", emptySymbol, fullSymbol, overlapSymbol)
|
legend := fmt.Sprintf("\n • Legend: %v (empty), %v (full), %v (overlap)", emptySymbol, fullSymbol, overlapSymbol)
|
||||||
@ -150,22 +163,22 @@ func (intvls *intervals) Print() string {
|
|||||||
overlapText += fmt.Sprintf("[%d,%d]", ovrlp.Low, ovrlp.High)
|
overlapText += fmt.Sprintf("[%d,%d]", ovrlp.Low, ovrlp.High)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, intvl := range intvls.Intervals {
|
for j, intvl := range intvls.Intervals {
|
||||||
if i != 0 {
|
if j != 0 {
|
||||||
intervalText += ", "
|
intervalText += ", "
|
||||||
}
|
}
|
||||||
intervalText += fmt.Sprintf("[%d,%d]", intvl.Low, intvl.High)
|
intervalText += fmt.Sprintf("[%d,%d]", intvl.Low, intvl.High)
|
||||||
for i := index; i < intvl.Low; i++ {
|
for i := index; i < intvl.Low; i++ {
|
||||||
index++
|
index++
|
||||||
graph += emptySymbol
|
graph += emptySymbol
|
||||||
if index%10 == 0 {
|
if index%blockSize == 0 {
|
||||||
graph += separator
|
graph += separator
|
||||||
numSeparators++
|
numSeparators++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := index; i <= intvl.High; i++ {
|
for i := index; i <= intvl.High; i++ {
|
||||||
if intvls.isAnOverlap(index, overlapped) {
|
if intvls.isOverlapping(index, overlapped) {
|
||||||
graph += overlapSymbol
|
graph += overlapSymbol
|
||||||
} else {
|
} else {
|
||||||
graph += fullSymbol
|
graph += fullSymbol
|
||||||
@ -185,14 +198,24 @@ func (intvls *intervals) Print() string {
|
|||||||
gapsText += fmt.Sprintf("[%d,%d]", gap.Low, gap.High)
|
gapsText += fmt.Sprintf("[%d,%d]", gap.Low, gap.High)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := index; i < intvls.MaxHigh; i++ {
|
for i := index + 1; i < intvls.MaxHigh; i++ {
|
||||||
graph += emptySymbol
|
graph += emptySymbol
|
||||||
|
if i%blockSize == 0 {
|
||||||
|
graph += separator
|
||||||
|
numSeparators++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
axisLegend := fmt.Sprintf(" %v", intvls.MinLow)
|
axisLegend := " "
|
||||||
for i := intvls.MinLow; i < intvls.MaxHigh+numSeparators-2; i++ {
|
numSeparators = 0
|
||||||
axisLegend += " "
|
for i := intvls.MinLow; i < intvls.MaxHigh/blockSize; i++ {
|
||||||
|
mark := fmt.Sprintf("%d", i*blockSize)
|
||||||
|
axisLegend += mark
|
||||||
|
limit := (blockSize - len(mark)) + 1
|
||||||
|
for j := 0; j < limit; j++ {
|
||||||
|
axisLegend += " "
|
||||||
|
}
|
||||||
}
|
}
|
||||||
axisLegend += fmt.Sprintf("%v", intvls.MaxHigh)
|
axisLegend += fmt.Sprintf("%v", intvls.MaxHigh)
|
||||||
graphText := fmt.Sprintf("\n\n%s\n╠%s╣", axisLegend, graph)
|
graphText := fmt.Sprintf("\n\n%s\n%s%s%s", axisLegend, leadingSymbol, graph, trailingSymbol)
|
||||||
return "\n" + introText + legend + intervalText + gapsText + overlapText + graphText + "\n"
|
return "\n" + introText + legend + intervalText + gapsText + overlapText + graphText + "\n"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user