一百块钱,如何分成十个随机数目的红包

今天逛 v 站,发现一个很有意思的问题“生成 10 个随机数 [0,100] 且最终 10 个随机数之和为 100 ,用 Python 如何实现?”,很有启发,记录下来。

高票回答: 在一根 1 到 100 的数轴上,随机取 9 个点,拿到 10 个线段。计算每个线段的长度,即是取值。

尝试按照高赞回答用 python 实现了一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import random

def divide(total, people):
s = set()
# 确定 people - 1 个不重复的分隔点,假设红包金额不能为0
while len(s) < people - 1:
s.add(random.randint(1, total))

# 从 0 开始分割
previous = 0
packets = list()

# 将分割点从小到大排好序,计算每一段之间的距离,即红包金额
for i in sorted(s):
packets.append(i - previous)
previous = i

# 加上最后一个红包
packets.append(total - previous)

# 打乱红包顺序
random.shuffle(packets)
return packets


packets = divide(100, 10)

for packet in packets:
print(packet)

注意:

  1. 这里主要是考虑算法,一些有效性验证没有考虑(总金额不够分出这么多红包、金额和人数为负数等)
  2. 以1元为基本单位,如果是要像微信红包那样精确到分,可以先将总金额乘100,然后结果里再除以100即可。
  3. 这里是完全随机的分配红包(假设随机数生成器可靠),实际场景下应该会有一些调整,做一下平滑处理以及黑人区分对待策略。