# Random integer numbers with fixed sum

I’m trying to create a function that returns an array of random integer numbers whose sum is fixed.

Here is my code:

function arraySum(a) {
return a.reduce((a, b) => a + b, 0)
}

function getRandomIntInclusive(min, max) {
const minCeil = Math.ceil(min)
const maxFloor = Math.floor(max)
return Math.floor(Math.random() * (maxFloor - minCeil + 1)) + minCeil
}

function randomNumbersWithFixedSum(quantity, sum) {
const randoms = [...Array(quantity - 1).keys()].map(q => getRandomIntInclusive(0, sum/quantity))
const last = sum - arraySum(randoms)
return [...randoms, last]
}

console.log(randomNumbersWithFixedSum(1, 100))
console.log(randomNumbersWithFixedSum(2, 100))
console.log(randomNumbersWithFixedSum(3, 100))
console.log(randomNumbersWithFixedSum(4, 100))
console.log(randomNumbersWithFixedSum(5, 100))

It works but it’s not exactly what I want. I would like that each number is random in the range [0, sum].
In the randomNumbersWithFixedSum function I forced that the first (quantity-1) numbers are in [0, sum/quantity], but I don’t like.

How can I create a really random numbers in [0, sum] whose sum is sum?

Stack Overflow Asked by whitecircle on December 28, 2020

This is a prime example where a recursive function can simplify the problem. Each execution only calculates one random number and then calls itself with updated arguments. See the comments for a description.

function getRandomNumberBetweenIncluding(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

function randomNumbersWithFixedSum(quantity, sum) {
// only a single number required; return the passed sum.
if (quantity === 1) {
return [sum];
}

// Create one random number and return an array containing that number
// as first item. Then use the spread operator and recursively execute
// the function again with a decremented quantity and the updated
// maximum possible sum.
const randomNum = getRandomNumberBetweenIncluding(0, sum);
return [
randomNum,
...randomNumbersWithFixedSum(quantity - 1, sum - randomNum),
];
}

console.log(randomNumbersWithFixedSum(1, 100));
console.log(randomNumbersWithFixedSum(2, 100));
console.log(randomNumbersWithFixedSum(3, 100));
console.log(randomNumbersWithFixedSum(4, 100));
console.log(randomNumbersWithFixedSum(5, 100));

Correct answer by str on December 28, 2020

What about the next solution:

1. At the first iteration, we try to get a random number between 0 and max - say we retrieve N.
2. At the second iteration - the max possible value cannot be greater than max - N (otherwise the sum will be greater than max).
3. Continue for quantity - 1 steps.
4. At the last step we have to use what is left until the max

function getRandomIntInclusive(min, max) {
const minCeil = Math.ceil(min)
const maxFloor = Math.floor(max)
return Math.floor(Math.random() * (maxFloor - minCeil + 1)) + minCeil
}

function randomNumbersWithFixedSum(quantity, sum) {
const result = [];
let total = 0;

for (let i = 0; i < quantity - 1; i++) {
let max = sum - total;
let num = getRandomIntInclusive(0, max);
result.push(num);
total += num;
}
result.push(sum - total);

return result;
}

console.log(randomNumbersWithFixedSum(1, 100))
console.log(randomNumbersWithFixedSum(2, 100))
console.log(randomNumbersWithFixedSum(3, 100))
console.log(randomNumbersWithFixedSum(4, 100))
console.log(randomNumbersWithFixedSum(5, 100))

Answered by falinsky on December 28, 2020

You could take only the rest of the sum for the max random number and shuffle the array later to omit large values only at the top of the array.

function shuffle(array) {
let i = array.length;
while (--i) {
let j = Math.floor(Math.random() * (i + 1)),
temp = array[j];
array[j] = array[i];
array[i] = temp;
}
return array;
}

function getRandomIntInclusive(min, max) {
const minCeil = Math.ceil(min)
const maxFloor = Math.floor(max)
return Math.floor(Math.random() * (maxFloor - minCeil + 1)) + minCeil
}

function randomNumbersWithFixedSum(length, sum) {
length--;
const randoms = Array.from({ length }, q => {
const r = getRandomIntInclusive(0, sum)
sum -= r;
return r;
});
return shuffle([...randoms, sum]);
}

console.log(randomNumbersWithFixedSum(5, 100))
console.log(randomNumbersWithFixedSum(4, 100))
console.log(randomNumbersWithFixedSum(3, 100))
console.log(randomNumbersWithFixedSum(2, 100))
console.log(randomNumbersWithFixedSum(1, 100))
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answered by Nina Scholz on December 28, 2020

## Related Questions

### Hexagon grid with border and image responsive (clip path probably)

2  Asked on December 22, 2021

### Find a cell containing a specific date

1  Asked on December 22, 2021

### Jeykll file to import not found or unreadable: base

1  Asked on December 22, 2021 by kyu96

### Unable to remove event listener from document

1  Asked on December 22, 2021 by prawn

### Invalid result adding the number of 1s in a binary number

2  Asked on December 20, 2021 by aworeham

### How to check if arraylist tree in Java is empty or not?

2  Asked on December 20, 2021

### How to print the elements of 3 different arrays by the order?

2  Asked on December 20, 2021 by fuzzyfiso

### Finding string elements of an array in another array

5  Asked on December 20, 2021 by p-emt

### Python SyntaxError vs TypeError for repeated keyword arguments

1  Asked on December 20, 2021

### How to plot several columns on the same line chart in R?

2  Asked on December 20, 2021 by user13953317

### Is there a way to craft URLs to fill forms faster?

1  Asked on December 20, 2021 by rosalind-goh

### How to merge dictionaries in np.ndarray into one dictionary?

1  Asked on December 20, 2021 by el_1988

### how to not use the default PHP 7.3 of Mac OSX Catalina 10.15.6 and use home brew php?

2  Asked on December 20, 2021

### Using BeautifulSoup to get the text after a strong tag, when that text is not within a … itself

1  Asked on December 20, 2021 by papelr

### Is it bad practice to return an array of objects directly?

2  Asked on December 20, 2021

### SQL Server: update on single record only updated half the varchar content

2  Asked on December 20, 2021

### How to decode hexadecimal string with “b” at the beggining?

1  Asked on December 20, 2021 by ger-cas

### infinite loop while using useEffect and redux store

0  Asked on December 20, 2021 by susanta

### Cannot convert textfield into string

1  Asked on December 20, 2021 by anuj-amin

### Is there multiple ways to cin vector elements?

1  Asked on December 20, 2021 by 2kbummer

### Ask a Question

Get help from others!