Add bisect utility
This is too common of an optimization to not have this readily accessible. And I kinda like how this worked out, too. Go is fun.
This commit is contained in:
31
utilities/bisect.go
Normal file
31
utilities/bisect.go
Normal file
@ -0,0 +1,31 @@
|
||||
package utilities
|
||||
|
||||
import "math"
|
||||
|
||||
// Bisect takes a known-good low and known-bad high value as the bounds
|
||||
// to bisect, and a function to test each value for success or failure.
|
||||
// If the function succeeds, the value is adjusted toward the maximum,
|
||||
// and if the function fails, the value is adjusted toward the minimum.
|
||||
// The final value is returned when the difference between the success
|
||||
// and the failure is less than or equal to the acceptance threshold
|
||||
// (usually 1, for integers).
|
||||
func Bisect[T Number](low, high, threshold T, tryFunc func(val T) bool) T {
|
||||
lastSuccess := low
|
||||
lastFailure := high
|
||||
currVal := low
|
||||
|
||||
for T(math.Abs(float64(lastFailure-lastSuccess))) > threshold {
|
||||
success := tryFunc(currVal)
|
||||
adjustment := (lastFailure - lastSuccess) / 2
|
||||
if success {
|
||||
lastSuccess = currVal
|
||||
} else {
|
||||
lastFailure = currVal
|
||||
adjustment = -adjustment
|
||||
}
|
||||
|
||||
currVal += adjustment
|
||||
}
|
||||
|
||||
return currVal
|
||||
}
|
Reference in New Issue
Block a user