import (
"fmt"
"math/rand"
"sync"
"time"
)
type RedPack struct {
Id string
Num int // 紅包個(gè)數(shù)
NumDelivered int // 已拆包數(shù)量
Amount int // 紅包金額
AmountDelivered int // 已發(fā)放金額
}
func NewRedPack(num int, amount int) *RedPack {
return &RedPack{Num: num, Amount: amount, NumDelivered: 0, AmountDelivered: 0}
}
func (pack *RedPack) get() int {
if pack.NumDelivered == pack.Num {
return 0
}
// 最后一個(gè)紅包直接返回
if pack.NumDelivered == pack.Num-1 {
amount := pack.Amount - pack.AmountDelivered
pack.NumDelivered += 1
pack.AmountDelivered = pack.Amount
return amount
}
// 動(dòng)態(tài)計(jì)算紅包平均值
avg := (pack.Amount - pack.AmountDelivered) / (pack.Num - pack.NumDelivered)
// 隨機(jī)計(jì)算紅包金額(1到2倍均值)
rand.Seed(time.Now().UnixNano())
calAmount := rand.Intn(2 * avg)
// 紅包金額最少1分
if calAmount == 0 {
calAmount = 1
}
// 保證后續(xù)每個(gè)人至少有1分
if (pack.Amount - pack.AmountDelivered - calAmount) < (pack.Num - pack.NumDelivered - 1) {
calAmount = pack.Amount - pack.AmountDelivered - (pack.Num - pack.NumDelivered - 1)
}
pack.NumDelivered += 1
pack.AmountDelivered += calAmount
return calAmount
}
func main() {
start:=time.Now().UnixNano()/1e6
wg := &sync.WaitGroup{}
for i := 0; i < 100000; i++ {
wg.Add(1)
go func(wg *sync.WaitGroup) {
redPack := NewRedPack(10, 10000)
total := 0
for i := 0; i < 10; i++ {
amount := redPack.get()
total += amount
}
wg.Done()
}(wg)
}
wg.Wait(
// 6核温鸽,耗時(shí)約9秒
fmt.Printf("100000個(gè)紅發(fā)發(fā)放完畢,耗時(shí):%d ms",(time.Now().UnixNano()/1e6-start))
}
思路
- 必須保證每個(gè)紅包至少1分錢(qián)