forked from jasder/antlr
Revert "[Go] Interval"
This commit is contained in:
parent
24c149603d
commit
38aaf88097
|
@ -14,9 +14,10 @@ type Interval struct {
|
||||||
Stop int
|
Stop int
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inclusive interval*/
|
/* stop is not included! */
|
||||||
func NewInterval(start, stop int) *Interval {
|
func NewInterval(start, stop int) *Interval {
|
||||||
i := new(Interval)
|
i := new(Interval)
|
||||||
|
|
||||||
i.Start = start
|
i.Start = start
|
||||||
i.Stop = stop
|
i.Stop = stop
|
||||||
return i
|
return i
|
||||||
|
@ -26,78 +27,16 @@ func (i *Interval) Contains(item int) bool {
|
||||||
return item >= i.Start && item < i.Stop
|
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 {
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
return strconv.Itoa(i.Start) + ".." + strconv.Itoa(i.Stop)
|
return strconv.Itoa(i.Start) + ".." + strconv.Itoa(i.Stop-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interval) length() int {
|
func (i *Interval) length() int {
|
||||||
return intMax(i.Stop - i.Start + 1,0)
|
return i.Stop - i.Start
|
||||||
}
|
}
|
||||||
|
|
||||||
type IntervalSet struct {
|
type IntervalSet struct {
|
||||||
|
@ -124,11 +63,11 @@ func (i *IntervalSet) first() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IntervalSet) addOne(v 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) {
|
func (i *IntervalSet) addRange(l, h int) {
|
||||||
i.addInterval(NewInterval(l, h))
|
i.addInterval(NewInterval(l, h+1))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IntervalSet) addInterval(v *Interval) {
|
func (i *IntervalSet) addInterval(v *Interval) {
|
||||||
|
@ -210,30 +149,31 @@ func (i *IntervalSet) length() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IntervalSet) removeRange(v *Interval) {
|
func (i *IntervalSet) removeRange(v *Interval) {
|
||||||
if v.Start == v.Stop {
|
if v.Start == v.Stop-1 {
|
||||||
i.removeOne(v.Start)
|
i.removeOne(v.Start)
|
||||||
} else if i.intervals != nil {
|
} 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]
|
ni := i.intervals[k]
|
||||||
// intervals are ordered
|
// intervals are ordered
|
||||||
if v.Stop <= ni.Start {
|
if v.Stop <= ni.Start {
|
||||||
return
|
return
|
||||||
} else if v.Start > ni.Start && v.Stop < ni.Stop {
|
} else if v.Start > ni.Start && v.Stop < ni.Stop {
|
||||||
i.intervals[k] = NewInterval(ni.Start, v.Start-1)
|
i.intervals[k] = NewInterval(ni.Start, v.Start)
|
||||||
x := NewInterval(v.Stop+1, ni.Stop)
|
x := NewInterval(v.Stop, ni.Stop)
|
||||||
// i.intervals.splice(k, 0, x)
|
// 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
|
return
|
||||||
} else if v.Start <= ni.Start && v.Stop >= ni.Stop {
|
} else if v.Start <= ni.Start && v.Stop >= ni.Stop {
|
||||||
// i.intervals.splice(k, 1)
|
// i.intervals.splice(k, 1)
|
||||||
i.intervals = append(i.intervals[0:k], i.intervals[k+1:]...)
|
i.intervals = append(i.intervals[0:k], i.intervals[k+1:]...)
|
||||||
k = k - 1
|
k = k - 1 // need another pass
|
||||||
continue
|
|
||||||
} else if v.Start < ni.Stop {
|
} 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 {
|
} 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
|
// intervals i ordered
|
||||||
if v < ki.Start {
|
if v < ki.Start {
|
||||||
return
|
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.splice(k, 1)
|
||||||
i.intervals = append(i.intervals[0:k], i.intervals[k+1:]...)
|
i.intervals = append(i.intervals[0:k], i.intervals[k+1:]...)
|
||||||
return
|
return
|
||||||
} else if v == ki.Start {
|
} else if v == ki.Start {
|
||||||
i.intervals[k] = NewInterval(ki.Start+1, ki.Stop)
|
i.intervals[k] = NewInterval(ki.Start+1, ki.Stop)
|
||||||
return
|
return
|
||||||
} else if v == ki.Stop {
|
} else if v == ki.Stop-1 {
|
||||||
i.intervals[k] = NewInterval(ki.Start, ki.Stop-1)
|
i.intervals[k] = NewInterval(ki.Start, ki.Stop-1)
|
||||||
return
|
return
|
||||||
} else if v < ki.Stop {
|
} else if v < ki.Stop-1 {
|
||||||
x := NewInterval(ki.Start, v-1)
|
x := NewInterval(ki.Start, v)
|
||||||
ki.Start = v + 1
|
ki.Start = v + 1
|
||||||
// i.intervals.splice(k, 0, x)
|
// i.intervals.splice(k, 0, x)
|
||||||
i.intervals = append(i.intervals[0:k], append([]*Interval{x}, i.intervals[k:]...)...)
|
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) + "'"))
|
names = append(names, ("'" + string(v.Start) + "'"))
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
if len(names) > 1 {
|
||||||
return "{" + strings.Join(names, ", ") + "}"
|
return "{" + strings.Join(names, ", ") + "}"
|
||||||
}
|
}
|
||||||
|
@ -322,14 +257,9 @@ func (i *IntervalSet) toIndexString() string {
|
||||||
names = append(names, strconv.Itoa(v.Start))
|
names = append(names, strconv.Itoa(v.Start))
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
if len(names) > 1 {
|
||||||
return "{" + strings.Join(names, ", ") + "}"
|
return "{" + strings.Join(names, ", ") + "}"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())
|
|
||||||
}
|
|
Loading…
Reference in New Issue