Added FindIntervalsForValue. Function renaming.
This commit is contained in:
		| @@ -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 + "╣" |  | ||||||
| // } |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user