From 7116b509e9b48339682d2f74df172fcdbb8ce006 Mon Sep 17 00:00:00 2001 From: duanhf2012 <6549168@qq.com> Date: Wed, 11 Sep 2024 14:50:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=9D=83=E9=87=8D=E9=9A=8F?= =?UTF-8?q?=E6=9C=BA=E7=9B=B8=E5=85=B3=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- util/rand/rand.go | 91 ------------------------------------ util/srand/slice.go | 107 +++++++++++++++++++++++++++++++++++++++++++ util/typedef/type.go | 25 ++++++++++ 3 files changed, 132 insertions(+), 91 deletions(-) delete mode 100644 util/rand/rand.go create mode 100644 util/srand/slice.go create mode 100644 util/typedef/type.go diff --git a/util/rand/rand.go b/util/rand/rand.go deleted file mode 100644 index ad98c49..0000000 --- a/util/rand/rand.go +++ /dev/null @@ -1,91 +0,0 @@ -package rand - -import ( - "math/rand" - "time" -) - -func init() { - rand.Seed(time.Now().UnixNano()) -} - -func RandGroup(p ...uint32) int { - if p == nil { - panic("args not found") - } - - r := make([]uint32, len(p)) - for i := 0; i < len(p); i++ { - if i == 0 { - r[0] = p[0] - } else { - r[i] = r[i-1] + p[i] - } - } - - rl := r[len(r)-1] - if rl == 0 { - return 0 - } - - rn := uint32(rand.Int63n(int64(rl))) - for i := 0; i < len(r); i++ { - if rn < r[i] { - return i - } - } - - panic("bug") -} - -func RandInterval(b1, b2 int32) int32 { - if b1 == b2 { - return b1 - } - - min, max := int64(b1), int64(b2) - if min > max { - min, max = max, min - } - return int32(rand.Int63n(max-min+1) + min) -} - -func RandIntervalN(b1, b2 int32, n uint32) []int32 { - if b1 == b2 { - return []int32{b1} - } - - min, max := int64(b1), int64(b2) - if min > max { - min, max = max, min - } - l := max - min + 1 - if int64(n) > l { - n = uint32(l) - } - - r := make([]int32, n) - m := make(map[int32]int32) - for i := uint32(0); i < n; i++ { - v := int32(rand.Int63n(l) + min) - - if mv, ok := m[v]; ok { - r[i] = mv - } else { - r[i] = v - } - - lv := int32(l - 1 + min) - if v != lv { - if mv, ok := m[lv]; ok { - m[v] = mv - } else { - m[v] = lv - } - } - - l-- - } - - return r -} diff --git a/util/srand/slice.go b/util/srand/slice.go new file mode 100644 index 0000000..89ddd84 --- /dev/null +++ b/util/srand/slice.go @@ -0,0 +1,107 @@ +package srand + +import ( + "github.com/duanhf2012/origin/v2/util/typedef" + "math/rand" + "slices" +) + +func Sum[E ~[]T, T typedef.Number](arr E) T { + var sum T + for i := range arr { + sum += arr[i] + } + return sum +} + +func SumFunc[E ~[]V, V any, T typedef.Number](arr E, getValue func(i int) T) T { + var sum T + for i := range arr { + sum += getValue(i) + } + return sum +} + +func Shuffle[E ~[]T, T any](arr E) { + rand.Shuffle(len(arr), func(i, j int) { + arr[i], arr[j] = arr[j], arr[i] + }) +} + +func RandOne[E ~[]T, T any](arr E) T { + return arr[rand.Intn(len(arr))] +} + +func RandN[E ~[]T, T any](arr E, num int) []T { + index := make([]int, 0, len(arr)) + for i := range arr { + index = append(index, i) + } + Shuffle(index) + if len(index) > num { + index = index + } + ret := make([]T, 0, len(index)) + for i := range index { + ret = append(ret, arr[index[i]]) + } + return ret +} + +func RandWeight[E ~[]T, T typedef.Integer](weights E) int { + totalWeight := Sum(weights) + if totalWeight <= 0 { + return -1 + } + + t := T(rand.Intn(int(totalWeight))) + for i := range weights { + if t < weights[i] { + return i + } + t -= weights[i] + } + return -1 +} + +func RandWeightFunc[E ~[]U, U any, T typedef.Integer](arr E, getWeight func(i int) T) int { + weights := make([]T, 0, len(arr)) + for i := range arr { + weights = append(weights, getWeight(i)) + } + return RandWeight(weights) +} + +func Get[E ~[]T, T any, U typedef.Integer](arr E, index U) (ret T, ok bool) { + if index < 0 || int(index) >= len(arr) { + return + } + ret = arr[index] + ok = true + return +} + +func GetPointer[E ~[]T, T any, U typedef.Integer](arr E, index U) *T { + if index < 0 || int(index) >= len(arr) { + return nil + } + return &arr[index] +} + +func GetFunc[E ~[]T, T any](arr E, f func(T) bool) (ret T, ok bool) { + index := slices.IndexFunc(arr, f) + if index < 0 { + return + } + + return arr[index], true +} + +func GetPointerFunc[E ~[]T, T any](arr E, f func(T) bool) *T { + index := slices.IndexFunc(arr, f) + if index < 0 { + return nil + } + + return &arr[index] +} \ No newline at end of file diff --git a/util/typedef/type.go b/util/typedef/type.go new file mode 100644 index 0000000..ce11cf5 --- /dev/null +++ b/util/typedef/type.go @@ -0,0 +1,25 @@ +package typedef + +type Signed interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 +} + +type Unsigned interface { + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 +} + +type Float interface { + ~float32 | ~float64 +} + +type Integer interface { + Signed|Unsigned +} + +type Number interface { + Signed|Unsigned +} + +type Ordered interface { + Number|Float|~string +}