Search code examples
javascriptrandomnumbersrangegenerate

Generate random numbers within specific range and with given conditions in javascript - times table


I have generated random set of numbers (generated number) for each individual multiplier (numbers from 2 - 10).

The code itself does generates the numbers although not as expected.

Current behaviour:

  • it renders numbers (sometimes repetetive) within an array (for example 2x4 and 2x4)
  • it renders array with different length each time
  • rendered numbers multiplication value is repetetive (if there's an object with 4x7 and 7x4 it should replace one of these sets with a new value)
  • number objects are rendered on given conditions (for example number 9 multiplier will render at least once but no more than 3 times)

Expected behaviour:

  • it renders unique set of numbers for each multiplier
  • renders the array with the same length all the time (with length === 18)
  • checks if multiplication of multiplier and generated number matches the value within the array, if so then it renders another set of numbers within (still within the conditions)

This is what I got so far

const randomNumbersGenerator = () => {
  function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min) + min);
  }

  const number2 = getRandomInt(0, 2);
  const number3 = getRandomInt(0, 3);
  const number4 = getRandomInt(0, 3);
  const number5 = getRandomInt(0, 3);
  const number6 = getRandomInt(1, 4);
  const number7 = getRandomInt(1, 4);
  const number8 = getRandomInt(1, 4);
  const number9 = getRandomInt(1, 4);
  const number10 = getRandomInt(0, 2);
  const number11 = getRandomInt(0, 3);

  const randomNumber = () => getRandomInt(2, 12);
  let current;
  const numbersArray = [];

  for (let i = 0; i < number2; i += 1) {
    if (numbersArray.indexOf((current = randomNumber())) === -1) {
      numbersArray.push({
        multiplier: 2,
        generated: current
      });
    }
  }

  for (let i = 0; i < number3; i += 1) {
    if (numbersArray.indexOf((current = randomNumber())) === -1) {
      numbersArray.push({
        multiplier: 3,
        generated: current
      });
    }
  }

  for (let i = 0; i < number4; i += 1) {
    if (numbersArray.indexOf((current = randomNumber())) === -1) {
      numbersArray.push({
        multiplier: 4,
        generated: current
      });
    }
  }

  for (let i = 0; i < number5; i += 1) {
    if (numbersArray.indexOf((current = randomNumber())) === -1) {
      numbersArray.push({
        multiplier: 5,
        generated: current
      });
    }
  }

  for (let i = 0; i < number6; i += 1) {
    if (numbersArray.indexOf((current = randomNumber())) === -1) {
      numbersArray.push({
        multiplier: 6,
        generated: current
      });
    }
  }

  for (let i = 0; i < number7; i += 1) {
    if (numbersArray.indexOf((current = randomNumber())) === -1) {
      numbersArray.push({
        multiplier: 7,
        generated: current
      });
    }
  }

  for (let i = 0; i < number8; i += 1) {
    if (numbersArray.indexOf((current = randomNumber())) === -1) {
      numbersArray.push({
        multiplier: 8,
        generated: current
      });
    }
  }

  for (let i = 0; i < number9; i += 1) {
    if (numbersArray.indexOf((current = randomNumber())) === -1) {
      numbersArray.push({
        multiplier: 9,
        generated: current
      });
    }
  }

  for (let i = 0; i < number10; i += 1) {
    if (numbersArray.indexOf((current = randomNumber())) === -1) {
      numbersArray.push({
        multiplier: 10,
        generated: current
      });
    }
  }

  for (let i = 0; i < number11; i += 1) {
    if (numbersArray.indexOf((current = randomNumber())) === -1) {
      numbersArray.push({
        multiplier: 11,
        generated: current
      });
    }
  }

  console.log(numbersArray);
  return numbersArray;
};
randomNumbersGenerator();

You can also check it out via the codeSandbox: https://codesandbox.io/s/upbeat-jang-coqd5?file=/src/index.js:660-672


Solution

  • I think this is what you are looking for. I took a completely different approach.

    First, I'm using a Map because it is simple to ensure uniqueness. (keys must be unique)

    Note I'm using a simple string for the key to ensure they are unique (using objects there get's a bit more complicated)

    The ranges array represents your 'number2, number3` etc.

    The loop starts at 2 to satisfy your multiplier range (2 - 11). This requires a bit of trickery to get index cone correctly.

    This generates unique pairs (as key) and the value of the map is the generated value and the multiplier multiplied together.

    The size and Map are printed in the console.

    const randomNumbersGenerator = () => {
      function getRandomInt(min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min) + min);
      }
      const randomNumber = () => getRandomInt(2, 12);
      const multiplierMap = new Map();
      const ranges = [[0, 2], [0, 3], [0, 3], [0, 3], [0, 3], [1, 4], [1, 4], [1, 4], [1, 4], [0, 2], [0, 3]];
      while(multiplierMap.size < 17) {
        for (let i = 2; i < ranges.length+1; i++) {
          const randomInt = randomNumber();
          if(Array.from(multiplierMap.values).includes(randomInt * i)){
            --i;
          } else {
            multiplierMap.set(randomInt + " " + i, randomInt * i);
          }
          if(multiplierMap.size === 18) break;
        }
      }
      console.log('MultiplierMap size: ', multiplierMap.size);
      for(let [pair, multiple] of multiplierMap){
        console.log('Generated Multiplier: ' + pair, '||', 'Generated * Multiplier: ' + multiple);
      }
      return multiplierMap;
    
    };
    randomNumbersGenerator();