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:

  1. Generating random values between 0 and 1
  2. Scaling them proportionally to reach the target total
  3. Ensuring no value exceeds the maximum limit
  4. 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) / sum helps 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.

Updated on: 2026-03-15T23:19:00+05:30

984 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements