Added FindIntervalsForValue. Function renaming.
This commit is contained in:
parent
21187ac4df
commit
7255f129f5
@ -9,7 +9,7 @@ type Interval struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (itvl Interval) String() string {
|
func (itvl Interval) String() string {
|
||||||
return fmt.Sprintf("(%v, %v) -> [%v]", itvl.Low, itvl.High, itvl.Object)
|
return fmt.Sprintf("(%v, %v)", itvl.Low, itvl.High)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ByLow implements sort.Interface for []Interval based on the Low field.
|
// ByLow implements sort.Interface for []Interval based on the Low field.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package interval_test
|
package interval_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"bitbucket.org/differenttravel/interval"
|
"bitbucket.org/differenttravel/interval"
|
||||||
@ -30,3 +31,33 @@ func TestInsert(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFindIntervalsForValue(t *testing.T) {
|
||||||
|
itvls := interval.NewIntervals(0, 100)
|
||||||
|
|
||||||
|
itvls.Add(&interval.Interval{Low: 5, High: 7})
|
||||||
|
itvls.Add(&interval.Interval{Low: 2, High: 4})
|
||||||
|
itvls.Add(&interval.Interval{Low: 3, High: 6})
|
||||||
|
itvls.Add(&interval.Interval{Low: 18, High: 20})
|
||||||
|
itvls.Add(&interval.Interval{Low: 20, High: 30})
|
||||||
|
itvls.Add(&interval.Interval{Low: 25, High: 28})
|
||||||
|
itvls.Add(&interval.Interval{Low: 30, High: 32})
|
||||||
|
|
||||||
|
valueToFind1 := 2
|
||||||
|
matches1 := itvls.FindIntervalsForValue(valueToFind1)
|
||||||
|
matches1Txt := fmt.Sprintf("\nFind(value=%d)={", valueToFind1)
|
||||||
|
for _, m := range matches1 {
|
||||||
|
matches1Txt += fmt.Sprintf("%v,", m)
|
||||||
|
}
|
||||||
|
matches1Txt += "}"
|
||||||
|
t.Logf(matches1Txt)
|
||||||
|
|
||||||
|
valueToFind2 := 4
|
||||||
|
matches2 := itvls.FindIntervalsForValue(4)
|
||||||
|
matches2Txt := fmt.Sprintf("\nFind(value=%d)={", valueToFind2)
|
||||||
|
for _, m := range matches2 {
|
||||||
|
matches2Txt += fmt.Sprintf("%v,", m)
|
||||||
|
}
|
||||||
|
matches2Txt += "}"
|
||||||
|
t.Logf(matches2Txt)
|
||||||
|
}
|
||||||
|
118
intervals.go
118
intervals.go
@ -12,12 +12,25 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
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()
|
Sort()
|
||||||
GetGaps() []*Interval
|
|
||||||
GetOverlapped() []*Interval
|
// Gaps first sorts (if necessary) and then returns the interval gaps
|
||||||
|
Gaps() []*Interval
|
||||||
|
|
||||||
|
// Overlapped first sorts (if necessary) and then returns the overlapped intervals
|
||||||
|
Overlapped() []*Interval
|
||||||
|
|
||||||
|
// FindIntervalsForValue returns all the intervals which contains the passed value
|
||||||
|
FindIntervalsForValue(value int) []*Interval
|
||||||
|
|
||||||
|
// Print first sorts (if necessary) and then displays graphically the interval sequence
|
||||||
Print() string
|
Print() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type intervals struct {
|
type intervals struct {
|
||||||
Intervals []*Interval
|
Intervals []*Interval
|
||||||
MinLow int
|
MinLow int
|
||||||
@ -43,6 +56,16 @@ func (intvls *intervals) Add(itvl *Interval) {
|
|||||||
intvls.Sorted = false
|
intvls.Sorted = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (intvls *intervals) FindIntervalsForValue(value int) []*Interval {
|
||||||
|
var matches []*Interval
|
||||||
|
for _, intvl := range intvls.Intervals {
|
||||||
|
if inBetweenInclusive(value, intvl.Low, intvl.High) {
|
||||||
|
matches = append(matches, intvl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matches
|
||||||
|
}
|
||||||
|
|
||||||
func (intvls *intervals) Sort() {
|
func (intvls *intervals) Sort() {
|
||||||
if !intvls.Sorted {
|
if !intvls.Sorted {
|
||||||
sort.Sort(ByLow(intvls.Intervals))
|
sort.Sort(ByLow(intvls.Intervals))
|
||||||
@ -50,7 +73,7 @@ func (intvls *intervals) Sort() {
|
|||||||
intvls.Sorted = true
|
intvls.Sorted = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (intvls *intervals) GetGaps() []*Interval {
|
func (intvls *intervals) Gaps() []*Interval {
|
||||||
intvls.Sort()
|
intvls.Sort()
|
||||||
gaps := []*Interval{}
|
gaps := []*Interval{}
|
||||||
lastHigh := intvls.MinLow
|
lastHigh := intvls.MinLow
|
||||||
@ -66,7 +89,7 @@ func (intvls *intervals) GetGaps() []*Interval {
|
|||||||
return gaps
|
return gaps
|
||||||
}
|
}
|
||||||
|
|
||||||
func (intvls *intervals) GetOverlapped() []*Interval {
|
func (intvls *intervals) Overlapped() []*Interval {
|
||||||
intvls.Sort()
|
intvls.Sort()
|
||||||
list := []*Interval{}
|
list := []*Interval{}
|
||||||
lastMinLow := math.MaxInt64
|
lastMinLow := math.MaxInt64
|
||||||
@ -102,11 +125,13 @@ func (intvls *intervals) isAnOverlap(value int, overlapped []*Interval) bool {
|
|||||||
|
|
||||||
func (intvls *intervals) Print() string {
|
func (intvls *intervals) Print() string {
|
||||||
intvls.Sort()
|
intvls.Sort()
|
||||||
|
|
||||||
// Available Symbols: ( ◯ ◌ ◍ ◎ ● ◉ ) , ( □ ■ ), ( ░ ▒ ▓ █ )
|
// Available Symbols: ( ◯ ◌ ◍ ◎ ● ◉ ) , ( □ ■ ), ( ░ ▒ ▓ █ )
|
||||||
emptySymbol := "◌"
|
emptySymbol := "◌"
|
||||||
fullSymbol := "◎"
|
fullSymbol := "◎"
|
||||||
overlapSymbol := "●"
|
overlapSymbol := "●"
|
||||||
separator := "║"
|
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)
|
||||||
intervalText := "\n • Intervals: "
|
intervalText := "\n • Intervals: "
|
||||||
@ -117,7 +142,7 @@ func (intvls *intervals) Print() string {
|
|||||||
blockSize := 10
|
blockSize := 10
|
||||||
numSeparators := 0
|
numSeparators := 0
|
||||||
|
|
||||||
overlapped := intvls.GetOverlapped()
|
overlapped := intvls.Overlapped()
|
||||||
for i, ovrlp := range overlapped {
|
for i, ovrlp := range overlapped {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
overlapText += ", "
|
overlapText += ", "
|
||||||
@ -152,7 +177,7 @@ func (intvls *intervals) Print() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gaps := intvls.GetGaps()
|
gaps := intvls.Gaps()
|
||||||
for i, gap := range gaps {
|
for i, gap := range gaps {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
gapsText += ", "
|
gapsText += ", "
|
||||||
@ -169,84 +194,5 @@ func (intvls *intervals) Print() string {
|
|||||||
}
|
}
|
||||||
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╣", axisLegend, graph)
|
||||||
return introText + legend + intervalText + gapsText + overlapText + graphText
|
return "\n" + introText + legend + intervalText + gapsText + overlapText + graphText + "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (i *Intervals) Insert(intvl *Interval) {
|
|
||||||
// i.Intervals = append(i.Intervals, intvl)
|
|
||||||
|
|
||||||
// if i.Root == nil {
|
|
||||||
// // create the root node
|
|
||||||
// i.Root = &Node{Value: intvl, Left: nil, Right: nil}
|
|
||||||
// } else {
|
|
||||||
// currentNode := i.Root
|
|
||||||
|
|
||||||
// // search for the next block or the last
|
|
||||||
// for {
|
|
||||||
// next := currentNode.Next()
|
|
||||||
// if next == nil {
|
|
||||||
// // append the new interval to the right of the last element
|
|
||||||
// if intvl.Low >= currentNode.Value.Low {
|
|
||||||
// currentNode.Right = &Node{Value: intvl, Left: currentNode, Right: nil}
|
|
||||||
// } else {
|
|
||||||
// newNode := &Node{Value: intvl, Left: currentNode.Left, Right: currentNode}
|
|
||||||
// currentNode.Left = newNode
|
|
||||||
// }
|
|
||||||
// return
|
|
||||||
// } else if currentNode.OverlapsWith(intvl) {
|
|
||||||
// if intvl.Low >= next.Value.Low {
|
|
||||||
// // insert the new interval to the right of the current node
|
|
||||||
// newNode := &Node{Value: intvl, Left: currentNode, Right: currentNode.Right}
|
|
||||||
// currentNode.Right = newNode
|
|
||||||
// } else {
|
|
||||||
// // insert the new interval to the left of the current node
|
|
||||||
// newNode := &Node{Value: intvl, Left: currentNode.Left, Right: currentNode}
|
|
||||||
// currentNode.Left = newNode
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (i *Intervals) appendInterval(intvl *Interval, n *Node) {
|
|
||||||
// if intvl.Low >= n.Value.Low {
|
|
||||||
// // insert the new interval to the right of the current node
|
|
||||||
// newNode := &Node{Value: intvl, Left: currentNode, Right: currentNode.Right}
|
|
||||||
// currentNode.Right = newNode
|
|
||||||
// } else {
|
|
||||||
// // insert the new interval to the left of the current node
|
|
||||||
// newNode := &Node{Value: intvl, Left: currentNode.Left, Right: currentNode}
|
|
||||||
// currentNode.Left = newNode
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (i *intervals) Print() string {
|
|
||||||
// emptySymbol := "░"
|
|
||||||
// fullSymbol := "█" // '▒' '▓'
|
|
||||||
// separator := "║"
|
|
||||||
// text := ""
|
|
||||||
// graph := "╠"
|
|
||||||
// index := 0
|
|
||||||
// for i, intvl := range i.Intervals {
|
|
||||||
// if i != 0 {
|
|
||||||
// text += ", "
|
|
||||||
// }
|
|
||||||
// text += fmt.Sprintf("[%d,%d]", intvl.Low, intvl.High)
|
|
||||||
// for i := index; i < intvl.Low; i++ {
|
|
||||||
// index++
|
|
||||||
// graph += emptySymbol
|
|
||||||
// if index%10 == 0 {
|
|
||||||
// graph += separator
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for i := index; i < intvl.High; i++ {
|
|
||||||
// index++
|
|
||||||
// graph += fullSymbol
|
|
||||||
// if index%10 == 0 {
|
|
||||||
// graph += separator
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return text + "\n" + graph + "╣"
|
|
||||||
// }
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user