发一个随机红包 100块钱给10个人 每个人最多12块钱 最少6块钱 怎么分

在微博上看到segmentfault上的一个题目,看了下问题,我自己想的就是先把每个人都分6元,然后在随机分配剩下的40元.看了下原题的答案,已经有这样的思路.哈哈.写下我的代码.
有两种做法:一种是从$leave里面随机 0 ~ ($max - $min)之间的数(可以是浮点数),然后随机用户的数组,抽取一个,判断两者相加是否大于$max,如果大于,跳过;小于的话就把相加的结果赋值给该用户. 
另一种做法是先随机抽取一个用户,在根据用户对比$max的差值随机一个数,再相加给该用户.我用的是这种.
/**
 *  $n = 10; // 人数
 *  $money = 100;  // 钱总和
 *  $min = 6;  // 下限6
 *  $max = 12; // 上线 12;
 */
function sendHongbao($money=100, $n=10, $min=6, $max=12){
    $arr = array_fill( 0, $n, $min); // 填充每个人的钱的数组
    $leave = $money - $n * $min; // 还剩余多少钱
    // 随机发放开始
    while ($leave) {
        // 随机用户
        $lucky = array_rand($arr, 1);
        if ($arr[$lucky] < $max){
            // 判断随机数的上限
            $randNum = mt_rand(1, ((($max - $arr[$lucky]) < $leave) ? ($max - $arr[$lucky]) : $leave ) );
            $arr[$lucky] += $randNum;
            $leave = $leave - $randNum;
        }
    }
    return $arr;
}
理论上每个人的随机获取的钱是接近10的.所以测试方法是不是正确,先把代码跑100万次,看看每个人的结果是不是接近于10.
写个简单的测试代码如下:
$sum = array(0,0,0,0,0,0,0,0,0,0);
for($i=0; $i<1000000; $i++){
    $res = sendHongbao();
    $sum[0] += $res[0];
    $sum[1] += $res[1];
    $sum[2] += $res[2];
    $sum[3] += $res[3];
    $sum[4] += $res[4];
    $sum[5] += $res[5];
    $sum[6] += $res[6];
    $sum[7] += $res[7];
    $sum[8] += $res[8];
    $sum[9] += $res[9];
}
echo "<pre>";
print_r($sum);
echo "</pre>";

结果如下:

Array
(
    [0] => 9995735
    [1] => 9998061
    [2] => 9973085
    [3] => 10001552
    [4] => 9998657
    [5] => 10002408
    [6] => 9999013
    [7] => 9998440
    [8] => 10006077
    [9] => 10026972
)
效率不高是个问题.如果有好的方法欢迎交流.
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页