Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-repeating arc4random_uniform

I've been trying to get non-repeating arc4random_uniform to work for ages now for my iPhone app. Been over all the questions and answers relating to this on stackoverflow with no luck and now I'm hoping someone can help me. What I want to do is is choose 13 different random numbers between 1 and 104. I have gotten it to work to the point of it choosing 13 different numbers, but sometimes two of them are the same.

int rand = arc4random_uniform(104);

This is what I'm doing, and then I'm using the rand to choose from an array. If it's easier to shuffle the array and then pick 13 from the top, then I'll try that, but I would need help on how to, since that seems harder.

Thankful for any advice.

like image 215
Jens Hendar Avatar asked Dec 03 '22 04:12

Jens Hendar


2 Answers

There's no guarantee whatsoever that ar4random_uniform() won't repeat. Think about it for a second -- you're asking it to produce a number between 0 and 103. If you do that one hundred and five times, it has no choice but to repeat one of its earlier selections. How could the function know how many times you're going to request a number?

You will either have to check the list of numbers that you've already gotten and request a new one if it's a repeat, or shuffle the array. There should be any number of questions on SO for that. Here's one of the oldest: What's the Best Way to Shuffle an NSMutableArray?.

There's also quite a few questions about non-repeating random numbers: https://stackoverflow.com/search?q=%5Bobjc%5D+non-repeating+random+numbers

like image 85
jscs Avatar answered Dec 28 '22 02:12

jscs


You can create an NSMutableSet and implement it like this:

NSMutableArray* numbers = [[NSMutableArray alloc] initWithCapacity: 13];
NSMutableSet* usedValues = [[NSMutableSet alloc] initWithCapacity: 13];

for (int i = 0; i < 13; i++) {
  int randomNum = arc4random_uniform(104);
  while ([usedValues containsObject: [NSNumber numberWithInt: randomNum]) {     
    randomNum = arc4random_uniform(104)
  }
  [[usedValues addObject: [NSNumber numberWithInt: randomNum];
  [numbers addObject: [[NSNumber numberWithInt: randomNum];
}
like image 31
HeWhoShallNotBeNamed Avatar answered Dec 28 '22 01:12

HeWhoShallNotBeNamed