Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

theprizerevealed

macrumors regular
Original poster
Feb 26, 2016
183
12
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?
 
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++) {
        [numberPool addObject:@(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.
 
...
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
 
  • Like
Reactions: firewood
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 ...

-(void)viewDidLoad
{
     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:
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.
 
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.
 
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!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.