75 lines
1.5 KiB
Go
75 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"math/rand"
|
|
"strings"
|
|
)
|
|
|
|
func first(s, arg string) agg { return &sbinop{s, opfirst} }
|
|
func last(s, arg string) agg { return &sbinop{s, oplast} }
|
|
func prefix(s, arg string) agg { return &sbinop{s, opprefix} }
|
|
func join(s, arg string) agg { return &sbinop{s, opjoin(arg)} }
|
|
func smin(s, arg string) agg { return &sbinop{s, opsmin} }
|
|
func smax(s, arg string) agg { return &sbinop{s, opsmax} }
|
|
|
|
type sbinop struct {
|
|
s string
|
|
f func(a, b string) string
|
|
}
|
|
|
|
func (o *sbinop) String() string { return o.s }
|
|
|
|
func (o *sbinop) merge(s string) { o.s = o.f(o.s, s) }
|
|
|
|
func opfirst(a, b string) string { return a }
|
|
func oplast(a, b string) string { return b }
|
|
|
|
func opprefix(a, b string) string {
|
|
for i := range a {
|
|
if i >= len(b) || a[i] != b[i] {
|
|
return a[:i]
|
|
}
|
|
}
|
|
return a
|
|
}
|
|
|
|
func opjoin(sep string) func(a, b string) string {
|
|
return func(a, b string) string {
|
|
return a + sep + b // TODO(kr): too slow? maybe strings.Join?
|
|
}
|
|
}
|
|
|
|
func opsmin(a, b string) string {
|
|
if strings.Compare(a, b) <= 0 {
|
|
return a
|
|
}
|
|
return b
|
|
}
|
|
|
|
func opsmax(a, b string) string {
|
|
if strings.Compare(a, b) >= 0 {
|
|
return a
|
|
}
|
|
return b
|
|
}
|
|
|
|
type sampler struct {
|
|
n int
|
|
s string
|
|
}
|
|
|
|
func sample(s, arg string) agg { return &sampler{1, s} }
|
|
func (p *sampler) String() string { return p.s }
|
|
func (p *sampler) merge(s string) {
|
|
p.n++
|
|
if rand.Intn(p.n) == 0 {
|
|
p.s = s
|
|
}
|
|
}
|
|
|
|
type constant string
|
|
|
|
func constf(init, arg string) agg { return constant(arg) }
|
|
func (c constant) String() string { return string(c) }
|
|
func (c constant) merge(string) {}
|