random char from weights support
parent
fe16e2325c
commit
ef314b6b33
|
|
@ -40,3 +40,32 @@ func RandomCharFromRange(start, stop byte) func() byte {
|
||||||
return start + byte(rand.Int()%int(1+stop-start))
|
return start + byte(rand.Int()%int(1+stop-start))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RandomCharFromWeights(m map[byte]int) func() byte {
|
||||||
|
type pair struct {
|
||||||
|
b byte
|
||||||
|
i int
|
||||||
|
}
|
||||||
|
result := make([]pair, 0, len(m))
|
||||||
|
sum := 0
|
||||||
|
for k, v := range m {
|
||||||
|
result = append(result, pair{b: k, i: v})
|
||||||
|
if v < 0 {
|
||||||
|
panic("each weight must each be natural")
|
||||||
|
}
|
||||||
|
sum += v
|
||||||
|
}
|
||||||
|
if sum <= 0 {
|
||||||
|
panic("weights must total nonzero")
|
||||||
|
}
|
||||||
|
return func() byte {
|
||||||
|
n := rand.Int() % sum
|
||||||
|
for _, v := range result {
|
||||||
|
n -= v.i
|
||||||
|
if n <= 0 {
|
||||||
|
return v.b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic("how")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,3 +14,18 @@ func TestRandom(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRandomCharFromWeights(t *testing.T) {
|
||||||
|
weights := map[byte]int{
|
||||||
|
'a': 1,
|
||||||
|
'b': 99,
|
||||||
|
}
|
||||||
|
foo := input.RandomCharFromWeights(weights)
|
||||||
|
for {
|
||||||
|
got := foo()
|
||||||
|
t.Logf("%c", got)
|
||||||
|
if got == 'a' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue