0

I am trying to create an array of 6 unique random numbers out of an array that the user gave his max value and min value (no lower then 0 and no higher then 37). What is incorrect?

    function randCalc(maxVal,minVal)
    {
        var maxVal = document.getElementById("maxRange").value;
        var minVal = document.getElementById("minRange").value;
        var tmpArray = new Array(6) ;
        tmpArray = [0];
        var realArray = new Array(6);
        realArray = tmpArray;
        if ((maxVal - minVal) < 6)
        {
            alert("</br>The difference cannot be lower then 6");
        }
        if (minVal<1)
        {
            alert("</br>The min value cannot be lower then 1");
        }
        if (maxVal>37)
        {
            throw alert("</br>The higher value cannot be higher then 37") ;
        }

        if(minVal>0 && ((maxVal-minVal)>=6)&& (maxVal<=37) )
        {
            document.writeln("</br>The random numbers are: ");
            for(i=0;i<=(6);i++)
            {
                var randLotto = Math.floor(Math.random() * (maxVal - minVal + 2) + minVal);
                tmpArray[i] = randLotto;
            }
            for(var j=0;j<=maxVal;j++)
            {
               for(var k=0;k<6;k++)
               {
                   if(tmpArray[j]==realArray[k])
                   {
                       j++;
                   }
                   else if(tmpArray[j]!=realArray[k])
                   {
                       realArray[k]=tmpArray[j];
                   }
               }
                if(realArray[6]!=null)
                {
                    break;
                }
            }
        }
    }

Any idea how to make it work?

KBE
  • 379
  • 3
  • 4
  • 15
  • 1
    Your `` tags should be either `
    ` or `
    ` (though that's just a simple syntax error, and almost certainly *not* your actual problem)..
    – David Thomas Mar 14 '14 at 08:33
  • 2
    Side note: You have a misunderstanding about JavaScript. The line `var tmpArray = new Array(6);` defines a variable, creates an array, and assigns it to the variable. The next line `tmpArray = [0];` creates a *new* array and assigns it to the variable. The first array is released and thrown away. Just `var tmpArray;` is all you need for that first line. – T.J. Crowder Mar 14 '14 at 08:34
  • 1
    I'd think of the problem differently. First separate the logic from the DOM. Then take a range from "min" to "max" numbers, shuffle it, and pick 6. – elclanrs Mar 14 '14 at 08:40
  • elclanrs - I get your idea, can you give some code to explain how to implement? – KBE Mar 14 '14 at 08:43

3 Answers3

1

Here's a core function for creating N random numbers between a min and max value.

function randCalc(maxVal, minVal, numRandoms) {
    var max = Math.max(maxVal, minVal);
    var min = Math.min(maxVal, minVal);
    // create a set to keep track of numbers we've already used so
    // we don't repeat any random numbers
    var set = {};
    var randoms = [];
    var rand;
    // prevent infinite loop if not given enough range
    if (max - min < numRandoms) {
        return randoms;
    }
    while (randoms.length < numRandoms) {
        rand = Math.floor((Math.random() * (max - min + 1) + min));
        // if we haven't already used this random number
        // then put it in our output array and add it to the set
        if (!(rand in set)) {
            randoms.push(rand);
            set[rand] = true;
        }
    }
    return randoms;
}

This function has nothing to do with the DOM or any particular limits of your problem. You can then wrap this with another function that retrieves info from the DOM, checks to see if everything is in range and then calls this core function.

function makeRandoms() {
    // retrieve DOM values and convert them to numbers
    var maxVal = document.getElementById("maxRange").value;
    var minVal = document.getElementById("minRange").value;
    if (!maxVal || !minVal) {
        alert("You must specify both a minimum and maximum value");
        return;
    }
    // convert both to numbers
    maxVal = parseInt(maxVal, 10);
    minVal = parseInt(minVal, 10);
    if (minVal < 1) {
        alert("The min value cannot be lower then 1");
        return;
    }
    if (maxVal > 37) {
        alert("The higher value cannot be higher then 37");
        return;
    }
    if (maxVal - minVal < 6) {
        alert("The difference cannot be lower then 6");
        return;
    }
    var randoms = randCalc(maxVal, minVal, 6);
    // output the randoms array here
    document.getElementById("output").innerHTML = JSON.stringify(randoms);
}

This makes a reusable function for generating N random values and keeps that utility function completely separate from your code that accesses the DOM in one particular page. Because of the way this uses a set to keep track of the used random numbers, this is scalable to very large numeric ranges or very large numbers of random numbers when some other algorithms that prebuild a list of all possible outputs are not as scalable.

Working demo: http://jsfiddle.net/jfriend00/48kCg/

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • jfriend00 - Thanks a lot your solution is working great and I spent some time understanding it. There was on condition I am not familiar with which assisted in the solution simplicity: if (!(rand in set)). – KBE Mar 14 '14 at 09:27
0

Here is a JS function, more simple, that does what you pretend:

function randCalc(maxVal,minVal){
    var text = "";
    var possible = [];
    for(var i = minVal; i < maxVal; i++){
        possible.push(i);
    }

    for( var i=0; i < 6; i++ ){
        if(text.length == 6){ 
            return text;
        }       

        text += possible[Math.floor(Math.random() * possible.length)];
        if(text > 6){
            text = text.substring(0, 6);
        }
    }
    return text;
}
Joao Almeida
  • 972
  • 2
  • 6
  • 19
0

It all looks pretty complicated. You can create an array with [n] random numbers between 0 and [max] using:

function createArrayWithUniqueRandomNumbers(n, max) {
  var checkobj = {}
     ,arr = [];

  while (arr.length < n) {
      var x = Math.floor(Math.random()*(max+1));
      if (!(x in checkobj)) {
          checkobj[x] = 1;
          arr.push(x);
      }
  }

  //sorting for convenience
  return arr.sort(function(a,b){return a-b;});
}
// usage
var myarr = createArrayWithUniqueRandomNumbers(6, 37);
KooiInc
  • 119,216
  • 31
  • 141
  • 177