2026-05-08 18:55:47 +08:00

60 lines
1.5 KiB
Go

package voiceroomredpacket
import (
"math/rand"
"net/http"
"time"
)
// splitRandomAmounts 按二倍均值法预拆拼手气金额。
func splitRandomAmounts(total int64, count int, seed int64) ([]int64, error) {
if total <= 0 {
return nil, NewAppError(http.StatusBadRequest, "voice_room_red_packet_amount_invalid", "totalAmount must be greater than 0")
}
if count <= 0 {
return nil, NewAppError(http.StatusBadRequest, "voice_room_red_packet_count_invalid", "totalCount must be greater than 0")
}
if total < int64(count) {
return nil, NewAppError(http.StatusBadRequest, "voice_room_red_packet_amount_invalid", "totalAmount must be greater than or equal to totalCount")
}
if seed == 0 {
seed = time.Now().UnixNano()
}
random := rand.New(rand.NewSource(seed))
amounts := make([]int64, 0, count)
remainAmount := total
remainCount := count
for remainCount > 1 {
avg := remainAmount / int64(remainCount)
maxAmount := avg * 2
keepForRest := int64(remainCount - 1)
if maxAmount > remainAmount-keepForRest {
maxAmount = remainAmount - keepForRest
}
if maxAmount < 1 {
maxAmount = 1
}
amount := int64(1)
if maxAmount > 1 {
amount = random.Int63n(maxAmount) + 1
}
amounts = append(amounts, amount)
remainAmount -= amount
remainCount--
}
amounts = append(amounts, remainAmount)
random.Shuffle(len(amounts), func(i, j int) {
amounts[i], amounts[j] = amounts[j], amounts[i]
})
return amounts, nil
}
func sumAmounts(values []int64) int64 {
var total int64
for _, value := range values {
total += value
}
return total
}