155 lines
4.1 KiB
Go
155 lines
4.1 KiB
Go
package intervals
|
|
|
|
import "fmt"
|
|
|
|
var blockSize = 10
|
|
|
|
type symbols struct {
|
|
emptySymbol string
|
|
fullSymbol string
|
|
overlapSymbol string
|
|
leadingSymbol string
|
|
trailingSymbol string
|
|
separator string
|
|
}
|
|
|
|
func newSymbols() symbols {
|
|
// Available Symbols: ( ◯ ◌ ◍ ◎ ● ◉ ) , ( □ ■ ), ( ░ ▒ ▓ █ )
|
|
return symbols{
|
|
emptySymbol: "◌",
|
|
fullSymbol: "◎",
|
|
overlapSymbol: "●",
|
|
leadingSymbol: "├",
|
|
trailingSymbol: "┤",
|
|
separator: "|",
|
|
}
|
|
}
|
|
|
|
func (intvls *intervals) report() string {
|
|
intvls.Sort()
|
|
symbols := newSymbols()
|
|
intro := intvls.buildHeading()
|
|
legend := intvls.buildLegend(symbols)
|
|
overlapText := intvls.reportOverlapped()
|
|
gapsText := intvls.reportGaps()
|
|
mergeText := intvls.reportMerged()
|
|
intervalText, graph := intvls.buildGraph(symbols)
|
|
axisLegend := intvls.buildAxisLegend()
|
|
graphWithLegend := fmt.Sprintf("\n\n%s\n%s%s%s", axisLegend, symbols.leadingSymbol, graph, symbols.trailingSymbol)
|
|
return "\n" + intro + intervalText + gapsText + overlapText + mergeText + legend + graphWithLegend + "\n"
|
|
}
|
|
|
|
func (intvls *intervals) buildGraph(symbols symbols) (string, string) {
|
|
index := intvls.MinLow
|
|
numSeparators := 0
|
|
graph := ""
|
|
intervalText := ""
|
|
intervalText, index, graph, numSeparators = intvls.reportIntervals(index, symbols, numSeparators)
|
|
graph, numSeparators, index = intvls.fillUntilTheEnd(index, symbols, graph, numSeparators)
|
|
return intervalText, graph
|
|
}
|
|
|
|
func (intvls *intervals) buildHeading() string {
|
|
introText := fmt.Sprintf("\n==================================\n REPORT (minLow=%d, maxHigh=%d)\n==================================", intvls.MinLow, intvls.MaxHigh)
|
|
return introText
|
|
}
|
|
|
|
func (intvls *intervals) buildLegend(symbols symbols) string {
|
|
legend := fmt.Sprintf("\n • Legend: %v (empty), %v (full), %v (overlap)", symbols.emptySymbol, symbols.fullSymbol, symbols.overlapSymbol)
|
|
return legend
|
|
}
|
|
|
|
func (intvls *intervals) reportIntervals(index int, symbols symbols, numSeparators int) (string, int, string, int) {
|
|
graph := ""
|
|
intervalText := "\n • Intervals: "
|
|
for j, intvl := range intvls.Intervals {
|
|
if j != 0 {
|
|
intervalText += ", "
|
|
}
|
|
intervalText += fmt.Sprintf("[%d,%d]", intvl.Low, intvl.High)
|
|
for i := index; i < intvl.Low; i++ {
|
|
index++
|
|
graph += symbols.emptySymbol
|
|
if index%blockSize == 0 {
|
|
graph += symbols.separator
|
|
numSeparators++
|
|
}
|
|
}
|
|
|
|
for i := index; i <= intvl.High; i++ {
|
|
if intvls.valueIsOverlapping(index, intvls.OverlappedList) {
|
|
graph += symbols.overlapSymbol
|
|
} else {
|
|
graph += symbols.fullSymbol
|
|
}
|
|
index++
|
|
if index%blockSize == 0 {
|
|
graph += symbols.separator
|
|
numSeparators++
|
|
}
|
|
}
|
|
}
|
|
return intervalText, index, graph, numSeparators
|
|
}
|
|
|
|
func (intvls *intervals) fillUntilTheEnd(index int, symbols symbols, graph string, numSeparators int) (string, int, int) {
|
|
for i := index + 1; i <= intvls.MaxHigh+1; i++ {
|
|
graph += symbols.emptySymbol
|
|
if i%blockSize == 0 {
|
|
graph += symbols.separator
|
|
numSeparators++
|
|
}
|
|
}
|
|
return graph, numSeparators, index
|
|
}
|
|
|
|
func (intvls *intervals) reportOverlapped() string {
|
|
overlapText := "\n • Overlapped: "
|
|
overlapped := intvls.Overlapped()
|
|
for i, ovrlp := range overlapped {
|
|
if i != 0 {
|
|
overlapText += ", "
|
|
}
|
|
overlapText += fmt.Sprintf("[%d,%d]", ovrlp.Low, ovrlp.High)
|
|
}
|
|
return overlapText
|
|
}
|
|
|
|
func (intvls *intervals) reportGaps() string {
|
|
gapsText := "\n • Gaps: "
|
|
gaps := intvls.Gaps()
|
|
for i, gap := range gaps {
|
|
if i != 0 {
|
|
gapsText += ", "
|
|
}
|
|
gapsText += fmt.Sprintf("[%d,%d]", gap.Low, gap.High)
|
|
}
|
|
return gapsText
|
|
}
|
|
|
|
func (intvls *intervals) reportMerged() string {
|
|
mergedText := "\n • Merged: "
|
|
merged := intvls.Merge()
|
|
for i, merge := range merged {
|
|
if i != 0 {
|
|
mergedText += ", "
|
|
}
|
|
mergedText += fmt.Sprintf("[%d,%d]", merge.Low, merge.High)
|
|
}
|
|
return mergedText
|
|
}
|
|
|
|
func (intvls *intervals) buildAxisLegend() string {
|
|
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)
|
|
return axisLegend
|
|
}
|