Welcome to WebmasterWorld Guest from 54.221.9.209

Forum Moderators: open

Message Too Old, No Replies

pair of random unique number

     
1:23 am on Apr 25, 2012 (gmt 0)

Junior Member

5+ Year Member

joined:Nov 16, 2008
posts: 136
votes: 0


hi,
i need an array that will contain 20 numbers. The numbers will be between 1 and 10. And i want these number to be there maximum 2 times so i will have two times each number in my array. But i need them to be insert randomly so they dont be a the same place in my array every. I tried something but it doesnt work. Heres my code :

var Cards = new Array();

while (Cards.length < 20) {

var rndNum = Math.floor(Math.random() * 10) + 1;
var found = false;
var count = 0;

for (i=0;i<Cards.length;i++) {
if (Cards[i] == rndNum) {
count +=1;
if (count<2) {
Cards[Cards.length] = rndNum;
}
else {
found = true;
break;
}
}
}
if(!found && count<2)Cards[Cards.length] = rndNum;
}


here's an output of what i get so far :
4,6,1,2,1,8,4,1,5,5,1,8,3,4,10,1,7,1,8,5

thanks for your help
1:57 am on Apr 25, 2012 (gmt 0)

New User

joined:Apr 15, 2012
posts: 7
votes: 0


You just need to alter the code in the for loop a little bit so that the loop will only be used to find whether there are more than or equal to two of the same number. You just need to check the value of count right after the loop and add the number to the array if there are less than two of the same number in the array.

Here's how I would change the code inside the while loop:


for (var i = 0; i < Cards.length; i++) {
if (Cards[i] == rndNum) {
count++;
if (count >= 2) {
break;
}
}
}

if (count < 2) {
Cards[Cards.length] = rndNum;
}


Hope this works.
2:06 am on Apr 25, 2012 (gmt 0)

Junior Member

5+ Year Member

joined:Nov 16, 2008
posts: 136
votes: 0


yep its working! Thanks for your help :)
4:16 pm on Apr 25, 2012 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member fotiman is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Oct 17, 2005
posts:4965
votes: 10


The problem with both of these approaches is that there is the potential for this to never complete (theoretically). You are generating random numbers, then determining if that number has been used already, and if so, ignoring that iteration and generating again, which is inefficient. Imagine if the random number generated was the same over and over.

You have a fixed number of items that you need to randomize, which is the following set of numbers:
1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10

So instead of generating a random number from 1 to 10, generate a random number from 1 to the size of the input, and then use that random number as the index to retrieve a number from your input data. For example:

var input = [1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10],
output = [],
rndNum;
while (input.length > 1) {
rndNum = Math.floor(Math.random() * (input.length - 1));
output.push(input.splice(rndNum, 1));
}
output.push(input.splice(0,1));


Output will now contain an array of random numbers pulled from input (and input will be empty as a result of using the slice operation to pull out values from the array). This reduces the number of random numbers that needs to be generated to 19 (the number of items in your input minus 1), and there's no duplication issues. More efficient, and smaller code. :)
6:13 am on Apr 26, 2012 (gmt 0)

Preferred Member

5+ Year Member

joined:Aug 18, 2008
posts:408
votes: 0


Or another simple option:
var cards = [1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10].sort(
function(){
return Math.random()-0.5;
}
);
alert(cards);
2:38 pm on Apr 26, 2012 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member fotiman is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Oct 17, 2005
posts:4965
votes: 10


That's a neat trick! :) However, it's slightly less efficient, only because it may require iterating through an array several times as it moves elements up and down in the array. This can be demonstrated with this:


var c = 0,
cards = [1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10].sort(
function(){
c++;
return Math.random()-0.5;
}
);
alert('Number of calls to Math.random = ' + c);


For me, this is averaging around 54 calls to Math.random() with that array.

So it's neat and compact, but slightly less efficient. I also think it's less obvious what it's doing, so adds complexity, even though it's a smaller chunk of code. Still, great to see another way to skin the cat. :)