I want to split 10
into an array of 4 random numbers, but neither can be 0
or higher than 4
. For example [1,2,3,4]
,
Given that:
In a collection of n positive numbers that sum up to S, at least one of them will be less than S divided by n (S/n)
and that you want a result set of exactly 4 numbers,
you could use the following algorithm:
Finally, extend the above algorithm with a condition to limit the upper limit of the random numbers.
In n steps, you can get a collection.
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getRandomCollection(min, max, length, sum) {
var collection = [];
var leftSum = sum - (min - 1);
for(var i = 0; i < length - 1; i++) {
var number = getRandomInt(min, Math.min(Math.ceil(leftSum/(length - i)), max));
leftSum -= number;
collection.push(number);
}
leftSum += min - 1;
while(leftSum > max) {
var randomIndex = Math.floor(Math.random() * collection.length);
if(collection[randomIndex] < max) {
collection[randomIndex]++;
leftSum--;
}
}
collection.push(leftSum);
return collection;
}
console.log(getRandomCollection(1, 4, 4, 10).join(' + ') + ' = 10');
console.log(getRandomCollection(3, 20, 10, 100).join(' + ') + ' = 100');
Reference
My answer using the same algorithm for another question