75 lines
1.6 KiB
Go
75 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"sort"
|
|
)
|
|
|
|
type Range struct{ Lower, Upper float64 }
|
|
|
|
func (r Range) Norm() Range {
|
|
if r.Lower > r.Upper {
|
|
return Range{r.Upper, r.Lower}
|
|
}
|
|
return r
|
|
}
|
|
|
|
func (r Range) String() string {
|
|
return fmt.Sprintf("[%g, %g]", r.Lower, r.Upper)
|
|
}
|
|
|
|
func (r1 Range) Union(r2 Range) []Range {
|
|
if r1.Upper < r2.Lower {
|
|
return []Range{r1, r2}
|
|
}
|
|
r := Range{r1.Lower, math.Max(r1.Upper, r2.Upper)}
|
|
return []Range{r}
|
|
}
|
|
|
|
func consolidate(rs []Range) []Range {
|
|
for i := range rs {
|
|
rs[i] = rs[i].Norm()
|
|
}
|
|
le := len(rs)
|
|
if le < 2 {
|
|
return rs
|
|
}
|
|
sort.Slice(rs, func(i, j int) bool {
|
|
return rs[i].Lower < rs[j].Lower
|
|
})
|
|
if le == 2 {
|
|
return rs[0].Union(rs[1])
|
|
}
|
|
for i := 0; i < le-1; i++ {
|
|
for j := i + 1; j < le; j++ {
|
|
ru := rs[i].Union(rs[j])
|
|
if len(ru) == 1 {
|
|
rs[i] = ru[0]
|
|
copy(rs[j:], rs[j+1:])
|
|
rs = rs[:le-1]
|
|
le--
|
|
i--
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return rs
|
|
}
|
|
|
|
func main() {
|
|
rss := [][]Range{
|
|
{{1.1, 2.2}},
|
|
{{6.1, 7.2}, {7.2, 8.3}},
|
|
{{4, 3}, {2, 1}},
|
|
{{4, 3}, {2, 1}, {-1, -2}, {3.9, 10}},
|
|
{{1, 3}, {-6, -1}, {-4, -5}, {8, 2}, {-6, -6}},
|
|
}
|
|
for _, rs := range rss {
|
|
s := fmt.Sprintf("%v", rs)
|
|
fmt.Printf("%40s => ", s[1:len(s)-1])
|
|
rs2 := consolidate(rs)
|
|
s = fmt.Sprintf("%v", rs2)
|
|
fmt.Println(s[1 : len(s)-1])
|
|
}
|
|
}
|