feat: math.

This commit is contained in:
tx7do
2024-09-23 21:31:56 +08:00
parent 8d39ab89d9
commit f7abc4e941
6 changed files with 502 additions and 15 deletions

View File

@@ -3,16 +3,50 @@ package rand
import (
"math/rand"
"time"
"github.com/tx7do/go-utils/math"
)
var RANDOM = rand.New(rand.NewSource(time.Now().UnixNano()))
var rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
func init() {
rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
}
func Float32() float32 {
return rnd.Float32()
}
func Float64() float64 {
return rnd.Float64()
}
func Intn(n int) int {
return rnd.Intn(n)
}
func Int31n(n int32) int32 {
return rnd.Int31n(n)
}
func Int63n(n int64) int64 {
return rnd.Int63n(n)
}
// RandomInt 根据区间产生随机数
func RandomInt(min, max int) int {
if min >= max {
return max
}
return RANDOM.Intn(max-min) + min
return min + Intn(max-min+1)
}
// RandomInt32 根据区间产生随机数
func RandomInt32(min, max int32) int32 {
if min >= max {
return max
}
return min + Int31n(max-min+1)
}
// RandomInt64 根据区间产生随机数
@@ -20,5 +54,96 @@ func RandomInt64(min, max int64) int64 {
if min >= max {
return max
}
return RANDOM.Int63n(max-min) + min
return min + Int63n(max-min+1)
}
// RandomString 随机字符串,包含大小写字母和数字
func RandomString(l int) string {
bytes := make([]byte, l)
for i := 0; i < l; i++ {
x := Intn(3)
switch x {
case 0:
bytes[i] = byte(RandomInt(65, 90)) //大写字母
case 1:
bytes[i] = byte(RandomInt(97, 122))
case 2:
bytes[i] = byte(Intn(10))
}
}
return string(bytes)
}
// RandomChoice 随机选择数组中的元素
func RandomChoice[T any](array []T, n int) []T {
if n <= 0 {
return nil
}
if n == 1 {
return []T{array[Intn(len(array))]}
}
tmp := make([]T, len(array))
copy(tmp, array)
if len(tmp) <= n {
return tmp
}
Shuffle(tmp)
return tmp[:n]
}
// Shuffle 随机打乱数组
func Shuffle[T any](array []T) {
if array == nil {
return
}
for i := range array {
j := Intn(i + 1)
array[i], array[j] = array[j], array[i]
}
}
// WeightedChoice 根据权重随机返回对应选项的索引O(n)
func WeightedChoice(weightArray []int) int {
if weightArray == nil {
return -1
}
total := math.SumInt(weightArray)
rv := Int63n(total)
for i, v := range weightArray {
if rv < int64(v) {
return i
}
rv -= int64(v)
}
return len(weightArray) - 1
}
// NonWeightedChoice 根据权重随机返回对应选项的索引O(n). 权重大于等于0
func NonWeightedChoice(weightArray []int) int {
if weightArray == nil {
return -1
}
for i, weight := range weightArray {
if weight < 0 {
weightArray[i] = 0
}
}
total := math.SumInt(weightArray)
rv := Int63n(total)
for i, v := range weightArray {
if rv < int64(v) {
return i
}
rv -= int64(v)
}
return len(weightArray) - 1
}