is there a random number generator such as this?

theprizerevealed

macrumors regular
Original poster
I wonder if xcode has a random number generator premade with these characteristics? The generator would take any number and use it to generate a number within that sequence, then then next time the generator is asked to generate a number it would choose another in that sequence, excepting the one chosen already?

For example, in the range 0 to 100....the generator chooses first 51 but when asked again to generate a number randomly it will given you another random number excepting 51...and so on as many times as you ask it to generate a number?

dantastic

macrumors 6502a
There is nothing built in to do that but it's a very simple problem.
Code:
NSUInteger randomNumbers = 101;
NSMutableArray *numberPool = [[NSMutableArray alloc] initWithCapacity:randomNumbers];
for (NSUInteger i = 0; i < randomNumbers; i++) {
}

while (numberPool.count > 0) {
NSUInteger nextIndex = arc4random_uniform(numberPool.count);
NSNumber *nextRandomNumber = numberPool[nextIndex];
[numberPool removeObjectAtIndex:nextIndex];
NSLog(@"%@", nextRandomNumber);
}
If you don't want your number repeated you have to build a pool of numbers, then randomly pick them one by one.

chown33

Moderator
Staff member
...
If you don't want your number repeated you have to build a pool of numbers, then randomly pick them one by one.
An alternative approach is to build a pool of numbers, shuffle them into random order, then pick them in sequence. Picking in sequence means taking the first number, removing it from the pool, repeating until the pool is empty. Refill, shuffle, and repeat as needed.

Here's an example of a good shuffle algorithm:
https://en.wikipedia.org/wiki/Fisher–Yates_shuffle

• firewood

AxoNeuron

macrumors 65816
Swift 3
Code:
var numbersArray : [Int] = Array(0...100);

func getRandom() -> Int
{
guard (numbersArray.count > 0) else { return -1 } //handle the condition where we've run out of numbers to pick

let randomIndex = Int(arc4random_uniform(UInt32(numbersArray.count + 1)));   // will pick a random number 0-100

let randomNum = numbersArray[randomIndex];

numbersArray.remove(at: randomIndex);

return randomNum;

}
Swift 2
Code:
var numbersArray : [Int] = Array(0...100);

func getRandom() -> Int
{
guard (numbersArray.count > 0) else { return -1 } //handle the condition where we've run out of numbers to pick

let randomIndex = Int(arc4random_uniform(UInt32(numbersArray.count + 1)));   // will pick a random number 0-100

let randomNum = numbersArray[randomIndex];

numbersArray.removeAtIndex(randomIndex);

return randomNum;

}
Objective-C
Code:
@interface ...
@property (strong, nonatomic) NSMutableArray *numbersArray;
@end

@implementation ...

{
self.numbersArray = [@[] mutableCopy];

for (int i = 0; i < 100; i++) {
[self.numbersArray addObject: [NSNumber numberWithInt:i]];
}

//we now have an array of numbers 0-100, range is easy to configure.
}

-(int)getRandom
{
if (self.numbersArray.count == 0) {
return -1; //guard for condition where numbersArray is empty
}

int index = (int)(arc4random_uniform(self.numbersArray.count + 1));

NSNumber *num = self.numbersArray[index];

[self.numbersArray removeAtIndex: index];

return [num intValue];
}

@end

Last edited:

AxoNeuron

macrumors 65816
I am not sure. I would only use a shuffling algorithm if I knew that the entire array would end up being used.

If there was a high probability that most of the shuffled numbers would never get used, then I would stick with using the random number generator to pick elements from an ordered array. In the end, if you have an array of 100 elements but your user only uses 10 of those elements, why go through the trouble of shuffling all 100 elements?

But if I was in a situation where 100% of the elements would always get used, then I would definitely prefer the array shuffling solution.

PhoneyDeveloper

macrumors 68040
You're suggesting that shuffling is more time consuming than picking random numbers. OP really hasn't given us a clear use case so we can know how big the list is and how much is likely to be used. I like shuffling because you do all the work up front. I don't believe that the difference in cpu time would be noticeable between the two algorithms.

BTW, removeAtIndex returns the value that's removed so you don't need two lines of code retrieve the item and remove it, as in your sample code.

AxoNeuron

macrumors 65816
You're suggesting that shuffling is more time consuming than picking random numbers. OP really hasn't given us a clear use case so we can know how big the list is and how much is likely to be used. I like shuffling because you do all the work up front. I don't believe that the difference in cpu time would be noticeable between the two algorithms.

BTW, removeAtIndex returns the value that's removed so you don't need two lines of code retrieve the item and remove it, as in your sample code.
Shuffling is, probably, more efficient on a per-element basis. In a direct comparison it would probably win.

But if you don't know how many numbers will be needed, it's probably best to dynamically generate a random number and pull it out of an ordered array, simply because the CPU will not be doing work on stuff that won't get used.

Good point about removeAtIndex, I never knew that!

PhoneyDeveloper

macrumors 68040
Good point about removeAtIndex, I never knew that!
Some smart guy about 30 years ago thought that up just so you could use it today.