How can I generate random integers from 0 - 4 in such a way that the same number is not generated twice consecutively? For example, if 3 is the number that is generated the first time then 0,1,2,4 will be the possible numbers for random generation the second time. If 2 is generated the second time then 0,1,3,4 will be the possible numbers for random generation the third time and so on.
-
You can't make random less random. Use an NSSet for uniquing. – CodaFi Mar 31 '13 at 20:53
-
possible duplicate of [Generate random number from given number](http://stackoverflow.com/questions/15680582/generate-random-number-from-given-number) – Martin R Mar 31 '13 at 20:55
-
See also http://stackoverflow.com/a/56656/1187415. – Martin R Mar 31 '13 at 21:00
-
3@MartinR - Those aren't dupes of his question. He is not asking for a shuffle. – Hot Licks Mar 31 '13 at 21:08
-
1@HotLicks: You are right. I overlooked the word *consecutive* when reading the question. Sorry! – Martin R Mar 31 '13 at 21:13
4 Answers
int oldrand = <prior random number>;
int adder = randomNumberGenerator() % 4;
int newrand = (oldrand + adder + 1) % 5;

- 47,103
- 17
- 93
- 151
-
I am not sure I understand how this solution works. I would appreciate it if you explain further. – oopology Apr 01 '13 at 03:15
-
2@oopology - You have a number 0 .. 4. You want another number in the same range, only not exactly the same number. So add any number between 1 and 4 to the first number, then, if the addition overflows, "wrap it around". So if your first number is 3 and you pick a random value 2, then add 3 + 2 + 1, you get 6, which is larger than your range. But 5 wraps to 0 and 6 wraps to 1, so your result is 1. – Hot Licks Apr 01 '13 at 03:30
-
thanks for the explanation. I wish I had enough up votes to give your explanation and answer an up vote. – oopology Apr 02 '13 at 07:38
uint32_t myRandomNumber(uint32_t upperBound, uint32_t avoid) {
if (avoid < upperBound) {
--upperBound;
}
uint32_t number = arc4random_uniform(upperBound);
if (number >= avoid) {
++number;
}
return number;
}
Call it like this the first time:
uint32_t number = myRandomNumber(5, 5);
Call it like this after the first time:
number = myRandomNumber(5, number);

- 375,296
- 67
- 796
- 848
it can be generated with using 2 arrays; 1 is sorted and the other is created by taking random objects form sorted like
-(NSMutableArray *)generateRandomNumbersFrom:(int) a to:(int)b
{
NSMutableArray * numbersWillBeChosen=[NSMutableArray new];
NSMutableArray * randomList=[NSMutableArray new];
//add the numbers that will create your ramdom list in order
for(int k=0;k<=(b-a);k++)
{
[numbersWillBeChosen addObject:@(a+k)];
}
//create random list
for (int p=(b-a)+1; p>0; p--) {
int rand= arc4random()%p;
[randomList addObject:[numbersWillBeChosen objectAtIndex:rand]];
[numbersWillBeChosen removeObjectAtIndex:rand];
}
NSLog(@"%@",randomList);
return randomList;
}
and you can call for your situation
randList=[self generateRandomNumbersFrom:0 to:4];

- 1,887
- 2
- 18
- 33
I tried Hot Lick's answer and it ended up generating duplicates for me (or out of range numbers). But it inspired me to come up with a solution that worked for me.
My code is C#, but you can modify it to suit your needs.
//Returns a random number not same as previous random number. ie. no 2 consec random
public static int NonConsecRandom(int max, int? lastNum=null)
{
if (lastNum == null)
return Random.Range(0, max);
int last = (int)lastNum;
return Random.Range(last + 1, last + max) % max;
}
Explanation:
first block just returns a random number if there was no previously generated number.
the second part generates a random number from the "other numbers".
For example if my "max" was 5, the possible random numbers are: 0, 1, 2, 3, 4
Lets say my last number was 2, now I want a random number among [3, 4, 0, 1]
So I generate a random between last+1 and last+max. i.e. between 3 (inclusive) and 7 (not inclusive)
[3, 4, 5, 6]
Mod any of those numbers with max (i.e. 5) and you'll get a random number in the desired range: [3 , 4, 0, 1]

- 49
- 4