0

I need to produce a random number ranging between 2 and 5 which is different each time. For example, I don't want two 3's in a row, or two 5's in a row. I then have to feed this into a for() loop, like this:

for(var i = 0; i < noBoxes.length; i+=randNumber) { //.... } 

How do I go about doing this?

4
  • 6
    "I don't want two 3's in a row, or two 5's in a row." - then it would not be random :) Commented May 10, 2012 at 13:23
  • So your want a random number from a list of numbers and remove this number from the list after you have it? Commented May 10, 2012 at 13:30
  • jbabey: It wouldn't be an evenly distributed, uncorrelated random number, but it's still stochastic. Commented May 10, 2012 at 13:30
  • Haha, yes you're right, it wouldn't be exactly random, but I assumed the initial number would be random, and then one would check this and change the second number accordingly. Commented May 10, 2012 at 13:32

4 Answers 4

2

Generate a random number up to n-1 and add it on, modulo the original range (shifting because the min is not 0):

i = some random int from 2 to 5 delta = randInt(3) // range of possible values from 2 to 5 is 4, minus 1 to // prevent getting all the way round to i again nextval = (i-2+delta)%4+2 // shift i down by the minimum, add the // delta and modulo the range 

This works because it adds up to 1 below the range, so it can never get back to the original number. For example, i=3, random int 0 to 2, so the max is (i-2+2)%3+2=3%3+2=0+2=2.

function differentRandInt(min,max,current) { var shiftedcurrent = current-min; var range = max-min+1; var delta = Math.floor((Math.random()*(range-1))+1); return (shiftedcurrent + delta)%range + min; } 

So if i=3, then i-min is 1, the range after adding the delta is 2,3,4, modulo 4 yielding 2,3,0, so adding the min gives us 4,5,2.

Sign up to request clarification or add additional context in comments.

5 Comments

How does that avoid what the OP is trying to avoid?
It adds on a delta that is limited to below the range (2 to 5). In effect it reduces the range of numbers to all except the current value, without having to re-generate the value if it collides.
I think there is a little error in your code, currently it won't produce the upper bound.
@Yoshi: sorry, missed the +1 on the range. As someone said, there are 3 hard problems in computer science: cache invalidation, and off by one errors.
Nonetheless, this is a really nice solution for this kind of problem. Definitely +1 from me ;)
2

Edit: more complete solution, and fixed off-by-one error:

var prev, randNumber; for(var i = 0; i < noBoxes.length; i+=randNumber) { do { randNumber = 2 + Math.floor(Math.random() * 4); } while(randNumber === prev); prev = randNumber; } 

4 Comments

This very likely produces the same numbers in a row at a lot of points.
It doesn't need to be iterative! Just limit the range of the random number you generate to the full range minus 1.
That's a nice idea Phil. Something along the lines of: produce random number in the range of 1..n-1; if random number == previous number, then random number = n; (assuming we count from 1...)
Or, like my answer, use modulo to wrap the range around!
0

Like so: http://jsbin.com/eyitav/

var loopingValues = [2, 3, 4, 5], len, value, rand; while ( (len=loopingValues.length) ) { rand = ~~( ( Math.random() % 1 ) * len); value = loopingValues.splice(rand, 1)[0]; //alert( value ) } 

Now you have your loop with value as the value 2, 3, 4 and 5 in random order.


Or easier to read: http://jsbin.com/ejizuw/

var loopingValues = [2, 3, 4, 5], value, rand; while ( loopingValues.length ) { rand = Math.random(); if ( rand === 1 ) { rand = 0; } rand = rand * loopingValues.length; rand = Math.floor(rand); value = loopingValues[rand]; loopingValues.splice(rand, 1); alert(value); } 

Comments

0

You can get your series in an array before you start looping-

var noBoxes={length:100}; var R= [2], r= 2, n= 2; while(R.length<noBoxes.length){ n= R[R.length-1]; while(r== n) r= 2+Math.floor(Math.random()*4) R.push(r); } And then loop through the array- for(var i = 0; i < noBoxes.length; i+=R[i]) { .... } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.