php 拼手气红包算法

/**
 * 拼手气红包分配算法
 * @param $money
 * @param $count
 * @return array|string
 */
function redAlgorithm($money, $count)
{
    // 参数校验
    if ($count * 0.01 > $money) {
        return "单个红包不能低于0.01元";
    }
    // 存放随机红包
    $redpack = [];
    // 未分配的金额
    $surplus = $money;
    for ($i = 1; $i <= $count; $i++) {
        // 安全金额
        $safeMoney = $surplus - ($count - $i) * 0.01;
        // 平均金额
        $avg = $i == $count ? $safeMoney : bcdiv($safeMoney, ($count - $i), 2);
        // 随机红包
        $rand = $avg > 0.01 ? mt_rand(1, $avg * 100) / 100 : 0.01;
        // 剩余红包
        $surplus = bcsub($surplus, $rand, 2);
        $redpack[] = $rand;
    }
    // 平分剩余红包
    $avg = bcdiv($surplus, $count, 2);
    for ($n = 0; $n < count($redpack); $n++) {
        $redpack[$n] = bcadd($redpack[$n], $avg, 2);
        $surplus = bcsub($surplus, $avg, 2);
    }
    // 如果还有红包没有分配完时继续分配
    if ($surplus > 0) {
        // 随机抽取分配好的红包,将剩余金额分配进去
        $keys = array_rand($redpack, $surplus * 100);
        // array_rand 第二个参数为 1 时返回的是下标而不是数组
        $keys = is_array($keys) ? $keys : [$keys];
        foreach ($keys as $key) {
            $redpack[$key] = bcadd($redpack[$key], 0.01, 2);
            $surplus = bcsub($surplus, 0.01, 2);
        }
    }
    // 红包分配结果
    return $redpack;
}

猜你喜欢

转载自blog.csdn.net/qq_43929048/article/details/129859488