1. 程式人生 > >發一個隨機紅包 100塊錢給10個人 每個人最多12塊錢 最少6塊錢 怎麼分

發一個隨機紅包 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
)
效率不高是個問題.如果有好的方法歡迎交流.