Revert "[Go] Interval"

This commit is contained in:
Terence Parr 2017-10-21 12:00:25 -07:00 committed by GitHub
parent 24c149603d
commit 38aaf88097
2 changed files with 23 additions and 196 deletions

View File

@ -14,9 +14,10 @@ type Interval struct {
Stop int
}
/* Inclusive interval*/
/* stop is not included! */
func NewInterval(start, stop int) *Interval {
i := new(Interval)
i.Start = start
i.Stop = stop
return i
@ -26,78 +27,16 @@ func (i *Interval) Contains(item int) bool {
return item >= i.Start && item < i.Stop
}
// Does this start completely before other? Disjoint
func (i *Interval) StartsBeforeDisjoint(other *Interval) bool{
return i.Start < other.Start && i.Stop < other.Start
}
// Does this start at or before other? Nondisjoint
func (i *Interval) StartsBeforeNonDisjoint(other *Interval) bool{
return i.Start <= other.Start && i.Stop >= other.Start
}
// Does this.a start after other.b? May or may not be disjoint
func (i *Interval) StartsAfter(other *Interval) bool{
return i.Start > other.Start
}
// Does this start completely after other? Disjoint
func (i *Interval) StartsAfterDisjoint(other *Interval) bool{
return i.Start > other.Stop
}
// Does this start after other? NonDisjoint
func (i *Interval) StartsAfterNonDisjoint(other *Interval) bool{
return i.Start>other.Start && i.Start <= other.Stop // i.Stop>=other.Stop implied
}
// Are both ranges disjoint? I.e., no overlap?
func (i *Interval) Disjoint(other *Interval) bool{
return i.StartsBeforeDisjoint(other) || i.StartsAfterDisjoint(other)
}
// Are two intervals adjacent such as 0..41 and 42..42?
func (i *Interval) Adjacent(other *Interval) bool{
return i.Start == other.Stop+1 || i.Stop == other.Start-1;
}
func (i *Interval) ProperlyContains(other *Interval) bool{
return other.Start >= i.Start && other.Stop <= i.Stop
}
// Return the interval computed from combining this and other
func (i *Interval) Union(other *Interval) *Interval{
return NewInterval(intMin(i.Start, other.Start), intMax(i.Stop, other.Stop))
}
// Return the interval in common between this and other
func (i *Interval) Intersection(other *Interval) *Interval{
return NewInterval(intMax(i.Start, other.Start), intMin(i.Stop, other.Stop))
}
// Return the interval with elements from this not in other;
// other must not be totally enclosed (properly contained)
// within this, which would result in two disjoint intervals
// instead of the single one returned by this method.
func (i *Interval) DifferenceNotProperlyContained(other *Interval) *Interval{
var diff *Interval = nil
if other.StartsBeforeDisjoint(i){
diff = NewInterval(intMax(i.Start, other.Stop +1), i.Stop)
}else if other.StartsAfterNonDisjoint(i){
diff = NewInterval(i.Start, other.Start -1)
}
return diff
}
func (i *Interval) String() string {
if i.Start == i.Stop {
if i.Start == i.Stop-1 {
return strconv.Itoa(i.Start)
}
return strconv.Itoa(i.Start) + ".." + strconv.Itoa(i.Stop)
return strconv.Itoa(i.Start) + ".." + strconv.Itoa(i.Stop-1)
}
func (i *Interval) length() int {
return intMax(i.Stop - i.Start + 1,0)
return i.Stop - i.Start
}
type IntervalSet struct {
@ -124,11 +63,11 @@ func (i *IntervalSet) first() int {
}
func (i *IntervalSet) addOne(v int) {
i.addInterval(NewInterval(v, v))
i.addInterval(NewInterval(v, v+1))
}
func (i *IntervalSet) addRange(l, h int) {
i.addInterval(NewInterval(l, h))
i.addInterval(NewInterval(l, h+1))
}
func (i *IntervalSet) addInterval(v *Interval) {
@ -210,30 +149,31 @@ func (i *IntervalSet) length() int {
}
func (i *IntervalSet) removeRange(v *Interval) {
if v.Start == v.Stop {
if v.Start == v.Stop-1 {
i.removeOne(v.Start)
} else if i.intervals != nil {
for k := 0; k < len(i.intervals); k++ {
k := 0
for n := 0; n < len(i.intervals); n++ {
ni := i.intervals[k]
// intervals are ordered
if v.Stop <= ni.Start {
return
} else if v.Start > ni.Start && v.Stop < ni.Stop {
i.intervals[k] = NewInterval(ni.Start, v.Start-1)
x := NewInterval(v.Stop+1, ni.Stop)
i.intervals[k] = NewInterval(ni.Start, v.Start)
x := NewInterval(v.Stop, ni.Stop)
// i.intervals.splice(k, 0, x)
i.intervals = append(i.intervals[0:k+1], append([]*Interval{x}, i.intervals[k+1:]...)...)
i.intervals = append(i.intervals[0:k], append([]*Interval{x}, i.intervals[k:]...)...)
return
} else if v.Start <= ni.Start && v.Stop >= ni.Stop {
// i.intervals.splice(k, 1)
i.intervals = append(i.intervals[0:k], i.intervals[k+1:]...)
k = k - 1
continue
k = k - 1 // need another pass
} else if v.Start < ni.Stop {
i.intervals[k] = NewInterval(ni.Start, v.Start-1)
i.intervals[k] = NewInterval(ni.Start, v.Start)
} else if v.Stop < ni.Stop {
i.intervals[k] = NewInterval(v.Stop+1, ni.Stop)
i.intervals[k] = NewInterval(v.Stop, ni.Stop)
}
k++
}
}
}
@ -245,18 +185,18 @@ func (i *IntervalSet) removeOne(v int) {
// intervals i ordered
if v < ki.Start {
return
} else if v == ki.Start && v == ki.Stop {
} else if v == ki.Start && v == ki.Stop-1 {
// i.intervals.splice(k, 1)
i.intervals = append(i.intervals[0:k], i.intervals[k+1:]...)
return
} else if v == ki.Start {
i.intervals[k] = NewInterval(ki.Start+1, ki.Stop)
return
} else if v == ki.Stop {
} else if v == ki.Stop-1 {
i.intervals[k] = NewInterval(ki.Start, ki.Stop-1)
return
} else if v < ki.Stop {
x := NewInterval(ki.Start, v-1)
} else if v < ki.Stop-1 {
x := NewInterval(ki.Start, v)
ki.Start = v + 1
// i.intervals.splice(k, 0, x)
i.intervals = append(i.intervals[0:k], append([]*Interval{x}, i.intervals[k:]...)...)
@ -295,14 +235,9 @@ func (i *IntervalSet) toCharString() string {
names = append(names, ("'" + string(v.Start) + "'"))
}
} else {
names = append(names, "'"+string(v.Start)+"'..'"+string(v.Stop)+"'")
names = append(names, "'"+string(v.Start)+"'..'"+string(v.Stop-1)+"'")
}
}
if len(names) == 0{
return "{}"
}
if len(names) > 1 {
return "{" + strings.Join(names, ", ") + "}"
}
@ -322,14 +257,9 @@ func (i *IntervalSet) toIndexString() string {
names = append(names, strconv.Itoa(v.Start))
}
} else {
names = append(names, strconv.Itoa(v.Start)+".."+strconv.Itoa(v.Stop))
names = append(names, strconv.Itoa(v.Start)+".."+strconv.Itoa(v.Stop-1))
}
}
if len(names) == 0{
return "{}"
}
if len(names) > 1 {
return "{" + strings.Join(names, ", ") + "}"
}

View File

@ -1,103 +0,0 @@
package antlr
import (
"testing"
)
func assertInterval(t *testing.T, i *Interval, l int){
if i.length() != l{
t.Errorf("For interval [%s] [%d] length is expected, [%d] is actual", i.String(), l, i.length())
}
}
func assertString(t *testing.T, expected string, result string){
if result != expected{
t.Errorf("expected: %s, result:%s", result, expected)
}
}
func TestDefaultIntervalLength(t *testing.T){
assertInterval(t, NewInterval(0,0), 1)
assertInterval(t, NewInterval(100, 100), 1)
assertInterval(t, NewInterval(200,100),0)
}
func TestIntervalSetAbsorb(t *testing.T){
s := NewIntervalSet()
s.addRange(10,20)
s.addRange(11,19)
assertString(t, "10..20", s.toIndexString())
}
func TestIntervalSetOverlap(t *testing.T){
s := NewIntervalSet()
s.addRange(10, 20)
s.addRange(15, 25)
assertString(t, "10..25", s.toIndexString())
}
func TestIntervalSetIndependent(t *testing.T) {
s := NewIntervalSet()
s.addRange(10, 20)
s.addRange(30, 40)
assertString(t, "{10..20, 30..40}", s.toIndexString())
}
func TestIntervalSetAdjoint(t *testing.T) {
s := NewIntervalSet()
s.addRange(10,20)
s.addRange(20, 30)
assertString(t, "10..30", s.toIndexString())
}
func TestIntervalSetBridge(t *testing.T){
s := NewIntervalSet()
s.addRange(10,20)
s.addRange(30,40)
s.addRange(20,30)
assertString(t, "10..40", s.toIndexString())
}
func TestIntervalSetBreak(t *testing.T){
s := NewIntervalSet()
s.addRange(10,40)
s.removeOne(25)
assertString(t, "{10..24, 26..40}", s.toIndexString())
}
func TestIntervalSetRemoveStart(t *testing.T){
s := NewIntervalSet()
s.addRange(10,40)
s.removeOne(10)
assertString(t, "11..40", s.toIndexString())
}
func TestIntervalSetRemoveEnd(t *testing.T){
s := NewIntervalSet()
s.addRange(10,40)
s.removeOne(40)
assertString(t, "10..39", s.toIndexString())
}
func TestIntervalSetRemoveSinglePoint(t *testing.T){
s := NewIntervalSet()
s.addOne(10)
s.addRange(100,200)
s.removeOne(10)
assertString(t, "100..200", s.toIndexString())
}
func TestIntervalSetRemoveRangeMid(t *testing.T) {
s := NewIntervalSet()
s.addRange(10,30)
s.removeRange(NewInterval(15,20))
assertString(t, "{10..14, 21..30}", s.toIndexString())
}
func TestIntervalSetRemoveEverything(t *testing.T){
s := NewIntervalSet()
s.addRange(10,20)
s.addRange(30,40)
s.removeRange(NewInterval(5, 50))
assertString(t, "{}", s.toIndexString())
}