lsndr

PHP: Делим число на n рандомных частей

Перед нами стоит задача разделить переданное число на определенное количество частей, которые вычисляются случайным образом, но в сумме дают исходное число. При этом не должно быть чего-то вроде 15, 1, 1, 2 (пример для числа 20).

Идеального решения на PHP не удалось найти, поэтому была написана следующая функция:

<?php
/*
 * @param int $number Number
 * @param int $parts_number Number of parts
 * @param bool $allow_zero Let the function use zero in a result array
 * 
 * @return bool|array
 * */
function expand_number(int $number, int $parts_number, bool $allow_zero = false)
{
    if($parts_number > $number)
        return false;

    $parts = [];
    $number_rest = $number;

    for ($i = 1; $i <= $parts_number; $i++) {
        if (!$allow_zero) {
            if ($i == $parts_number)
                $new_number = $number_rest;
            else {
                $max = intval($i == $parts_number ? $number_rest : ($number_rest - ($parts_number - $i)) / 2);
                $new_number = rand(1, $max);
            }
        } else {
            $new_number = rand(0, $number_rest);
        }

        $number_rest -= $new_number;
        $parts[] = $new_number;
    }

    shuffle($parts);
    return $parts;
}
?>

Описание

int $number — это наше число, которое требуется разделить.
int $parts_number — количество частей.
bool $allow_zero — разрешает использовать ноль в результате

Функция возвращает массив с числами, либо false если $parts_number больше чем $number

Тесты

Результат работы для числа 20 при делении на 5:

Array
(
    [0] => 1
    [1] => 6
    [2] => 3
    [3] => 2
    [4] => 8
)

Результат работы для числа 143 при делении на 7:

Array
(
    [0] => 65
    [1] => 12
    [2] => 19
    [3] => 3
    [4] => 22
    [5] => 2
    [6] => 20
)
20 февраля   PHP   Функция