# How can I efficiently select several unique random numbers from 1 to 50, excluding x?

I have 2 numbers which are between 0 and 49. Let’s call them `x`

and `y`

. Now I want to get a couple of other numbers which are not x or y, but are also between `0`

and `49`

(I am using Objective C but this is more of a general theory question I think?).

Method I thought of is:

```
int a;
int b;
int c;
do {
a = arc4random() % 49;
} while ((a == x) || (a == y));
do {
b = arc4random() % 49;
} while ((b == x) || (b == y) || (b == a));
do {
c = arc4random() % 49;
} while ((c == x) || (c == y) || (c == a) || (c == b));
```

But it seem kind of bad to me, I don’t know, I am just trying to learn to be a better programmer, what would be the most elegant way to do this for best practices?

- iPhone NSDate eg. next Friday
- UICollectionView: How to define a UICollectionViewLayout that supports horizontally and vertically scrolling?
- NSString to CFStringRef and CFStringRef to NSString in ARC?
- Adding particular date in default calender as an event
- ABMultiValueGetCount - kABPersonSocialProfileProperty always returns 0 ? How can I get Facebook details from address book?
- Cocoapods: use_frameworks! causes linker errors

### 5 Solutions Collect From Internet About “How can I efficiently select several unique random numbers from 1 to 50, excluding x?”

You can use something called the Fisher-Yates shuffle. It’s an efficient algorithm for producing a randomly ordered list of values from some set. You would first exclude N from the list of values from which to get random values, and then perform the shuffle.

You should shuffle an array of numbers (of values [0, …, 49] in your case; you can also exclude your `x`

and `y`

from that array if you already know their values), then grab the first N values (however many you’re seeking) from the shuffled array. That way, all the numbers are randomly of that range, and not “seen before”.

I’d do something more along the lines of:

```
NSMutableSet * invalidNumbers = [NSMutableSet set];
[invalidNumbers addObject:[NSNumber numberWithInt:x]];
[invalidNumbers addObject:[NSNumber numberWithInt:y]];
int nextRandom = -1;
do {
if (nextRandom >= 0) {
[invalidNumbers addObject:[NSNumber numberWithInt:nextRandome]];
}
nextRandom = arc4random() % 49;
} while ([invalidNumbers containsObject:[NSNumber numberWithInt:nextRandom]]);
```

You could add x, y and the new number to a data structure that you can use as a `set`

and do something like (in pseudo-code; the `set`

structure needs something like `push`

to add values and `in`

for checking membership):

```
number_of_randoms = 2;
set.push(x);
set.push(y);
for (i = 0; i<number_of_randoms; i++) {
do {
new_random = arc4random() % 49;
} while !set.in(new_random);
set.push(new_random);
}
```

So if objc has something appropriate, this is easy…[aha, it does, see Dave DeLong’s post].

This algorithm makes sense if number_of_randoms is much less than 49; if they are comparable then you should one of the shuffle (aka *permutation*) ideas.

First, make a set of valid numbers:

```
// Create a set of all the possible numbers
NSRange range = { 0, 50 };// Assuming you meant [0, 49], not [0, 49)
NSMutableSet *numbers = [NSMutableSet set];
for (NSUInteger i = range.location; i < range.length; i++) {
NSNumber *number = [NSNumber numberWithInt:i];
[numbers addObject:number];
}
// Remove the numbers you already have
NSNumber *x = [NSNumber numberWithInt:(arc4random() % range.length)];
NSNumber *y = [NSNumber numberWithInt:(arc4random() % range.length)];
NSSet *invalidNumbers = [NSSet setWithObjects:x, y, nil];
[numbers minusSet:invalidNumbers];
```

Then, if you don’t need the numbers to be guaranteed to be random, you could use `-anyObject`

and `-removeObject`

to pull out a couple of other numbers. If you do need them to be random, then follow LBushkin’s answer, but be careful not to accidentally implement Sattolo’s algorithm:

```
// Shuffle the valid numbers
NSArray *shuffledNumbers = [numbers allObjects];
NSUInteger n = [shuffledNumbers count];
while (n > 1) {
NSUInteger j = arc4random() % n;
n--;
[shuffledNumbers exchangeObjectAtIndex:j withObjectAtIndex:n];
}
```

- Executing shell commands with NSTask – Objective-C Cocoa
- iPhone: How do I get the file path of an image saved with UIImageWriteToSavedPhotosAlbum()?
- Android equivalent to NSNotificationCenter
- Is it safe to delete sqlite's WAL file?
- Add a symbolic breakpoint on a selector in Xcode
- is it possible to change the name of an iOS app via xcode?
- UICollectionView with multi-select won't select more than a dozen of items
- How to create MKCircle in Swift?
- how to post an image to the web server
- Mobile Safari multi select bug
- Error in for loop CGFloat
- How to save image using libcurl
- ios5 – size of modal view controller with storyboard
- Retina display core graphics font quality
- Objective C test class using Swift code