Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Create array of integer values limited by n offsets and max sum of all together

Tags:

arrays

php

As the title say ... lets just look at the code (explains it better):

$maxItemAmount = 10;
$maxItemQtyTotal = 40; 

$qtyMap = array_map(function () use ($maxItemQtyTotal) {
    // returns something with rand()
    // but relative to $maxItemQtyTotal
}, array_fill(0, $maxItemAmount, null));

// expecting: (10 items with a total qty of 40)
// [
//     // numeric key => qty
//     0 => 3, // 3 total
//     1 => 4, // 7 total
//     2 => 9, // 16 total 
//     3 => 2, // 18 ...
//     4 => 6, // 24
//     5 => 1, // 25
//     6 => 2, // 27
//     7 => 8, // 35
//     8 => 3, // 38
//     9 => 2, // 40
// ]

So i found this nice "trick" to create the amount of offsets in the array which allows me to return the value using a callback.

What i now search is a way to return a random number, but relative to the given input $maxItemQtyTotal.

Another example:

$maxItemAmount = 4;
$maxItemQtyTotal = 81;

// expecting: (4 items with a total qty of 81)
// [
//     // numeric key => qty
//     0 => 11, // 11 total
//     1 => 5,  // 16 total
//     2 => 42, // 58 total
//     3 => 23, // 81 total
// ]

I cannot return rand(1, $maxItemQtyTotal). I would have to return rand(1, $n) where $n is the max qty divided by max items

but still random and what ever is left from the last rand(1, $n) added to the next ones?

I hope i could describe it a little :)

like image 241
cottton Avatar asked Jan 30 '26 22:01

cottton


1 Answers

I am not sure about the array_fill, but I know it is possible to do so by creating a simple function with a for loop:

function randomNumbers(int $N, int $M): array {
    $nums = [];
    for ($i = 0, $runningTotal = 0; $i < $N - 1; $i++) {
        $ceil = ceil(($M - $runningTotal) / ($N - $i)); // What is the maximum reasonable number we can push into array
        $nums[] = $num = mt_rand(1, $ceil);
        $runningTotal += $num;
    }
    $nums[] = $M - array_sum($nums);
    shuffle($nums); // Randomize elements so that they appear more random
    return $nums;
}

This will generate an array of N random numbers which all add up to M.

like image 98
Dharman Avatar answered Feb 01 '26 16:02

Dharman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!