Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Selected Reading
Split number into 4 random numbers in JavaScript
We need to write a JavaScript function that takes a total number and a maximum value, then generates four random numbers that sum to the total while ensuring none exceeds the maximum.
The function should generate four random numbers where:
- All four numbers sum to the given total
- No number exceeds the specified maximum
- Repetition of numbers is allowed
For example, if the total is 10 and maximum is 4, a valid output could be [3, 2, 3, 2].
Algorithm Overview
The algorithm works by:
- Generating random values between 0 and 1
- Scaling them proportionally to reach the target total
- Ensuring no value exceeds the maximum limit
- Repeating until the sum matches exactly
Implementation
const total = 10;
const max = 4;
const fillWithRandom = (max, total, len = 4) => {
let arr = new Array(len);
let sum = 0;
do {
// Generate random values
for (let i = 0; i < len; i++) {
arr[i] = Math.random();
}
// Calculate current sum
sum = arr.reduce((acc, val) => acc + val, 0);
// Scale values to approach target total
const scale = (total - len) / sum;
arr = arr.map(val => Math.min(max, Math.round(val * scale) + 1));
// Recalculate sum after scaling
sum = arr.reduce((acc, val) => acc + val, 0);
} while (sum !== total); // Repeat until exact match
return arr;
};
console.log("Target total:", total);
console.log("Maximum value:", max);
console.log("Generated numbers:", fillWithRandom(max, total));
console.log("Verification:", fillWithRandom(max, total).reduce((a, b) => a + b, 0));
Target total: 10 Maximum value: 4 Generated numbers: [ 3, 3, 2, 2 ] Verification: 10
How It Works
The function uses a loop-and-retry approach:
// Test with different parameters
const testFunction = (total, max) => {
const result = fillWithRandom(max, total);
const sum = result.reduce((a, b) => a + b, 0);
const withinLimit = result.every(num => num <= max);
console.log(`Total: ${total}, Max: ${max}`);
console.log(`Result: [${result.join(', ')}]`);
console.log(`Sum matches: ${sum === total}`);
console.log(`All within limit: ${withinLimit}`);
console.log("---");
};
testFunction(15, 5);
testFunction(8, 3);
Total: 15, Max: 5 Result: [4, 4, 3, 4] Sum matches: true All within limit: true --- Total: 8, Max: 3 Result: [2, 2, 2, 2] Sum matches: true All within limit: true ---
Key Points
- The algorithm may take several iterations to find a valid combination
- Each run produces different results due to randomization
- The scaling factor
(total - len) / sumhelps approach the target efficiently - Adding 1 to each scaled value ensures minimum positive integers
Conclusion
This function effectively splits a number into four random parts while respecting constraints. The iterative approach ensures exact sum matching while maintaining randomness in distribution.
Advertisements
