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 }