0

I am making a random ticket generator which asks range and when pressing button generates a random number in the range of that number. The code is missing an important part: generated numbers can't repeat. Probably the use of list in Math.random is also false.

function random_number() {
  var list = [];
  var range = document.getElementById('range').value;
  for (var i = 1; i <= range; i++) {
    list.push(i);
  }

  var random = Math.floor(Math.random(list) * range) + 1;

  if (document.getElementById('display').innerText = random) {}
}
<input id="range" type="text">
<br/>
<button onclick="random_number()" "delete_number()" class="button"> <span id="display"></span> </button>
  • 7
    Create an array of the numbers. Shuffle array. Pop numbers off until array.length == 0 – Wainage Oct 18 '18 at 18:14
  • As in they can't repeat at all in the string (`01234567890`) or as in they can't repeat right after eachother (`01234566789`)? – h2ooooooo Oct 18 '18 at 18:17
  • Possible duplicate of [How to randomly generate numbers without repetition in javascript?](https://stackoverflow.com/questions/15585216/how-to-randomly-generate-numbers-without-repetition-in-javascript) –  Oct 18 '18 at 18:23
  • The design for using this is a bit funny. Not sure if it's just because it's example code, but do you reset the list of random numbers if the range changes? I don't see a listener there so it's hard to write code to do what you want using the UI provided. – Jonathan Rys Oct 18 '18 at 18:29

2 Answers2

0

If supporting newer syntax or using babel, use a Set, like const numbers = new Set(); And add each generated number to a the set. The set will work so that each item is unique.

You can also find an es5 way to make a set.

Tamb
  • 748
  • 11
  • 20
0

This may not be the best method as it uses recursion, but it works. It gets a random number and adds it to a list of used numbers, making sure not to return a number that is in the array of already used numbers.

There are plenty of ways to do this, this is just one of them.

var usedNumbers = []

var randomNumber = function () {
  var range = 10
  
  // If the list of used numbers is the same as the range, we have gone
  // through all numbers
  if (usedNumbers.length === range) {
    console.error('Max numbers reached')
    return false
  }
  
  var list = []
  for (var i = 1; i <= range; i++) {
    list.push(i);
  }
  var random = Math.floor(Math.random(list) * range) + 1
  
  // If the number appears in the list of used numbers, re-run the function
  if (usedNumbers.indexOf(random) != -1) {
    return randomNumber()
  }
  
  // add the number to the list
  usedNumbers.push(random)
  return random
}

// Get a random number 11 times (last one will return false)
for (var i = 0; i <= 10; i++) {
  console.log(randomNumber())
}

Here's another method based on @Wainage comment of creating an array and popping the number off it.

var upperLimit = 10
var range = []
// Add the range of numbers to the array
for (var i = 1; i <= upperLimit; i++) {
  range.push(i)
}

var randomNumber = function () {
  // pick a random number from the array
  var random = range[Math.floor(Math.random() * range.length)]
  // remove it from the array
  range.splice(range.indexOf(random), 1)
  return random
}

// Call a random number 15 times
// If no number, it will return undefined
for(var i = 0; i < 15; i++) {
  console.log(randomNumber())
}
Cjmarkham
  • 9,484
  • 5
  • 48
  • 81