is there a random number generator such as this?

Discussion in 'iOS Programming' started by theprizerevealed, Oct 13, 2016.

  1. theprizerevealed macrumors member

    Joined:
    Feb 26, 2016
    #1
    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?
     
  2. dantastic macrumors 6502a

    dantastic

    Joined:
    Jan 21, 2011
    #2
    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.
     
  3. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #3
    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
     
  4. AxoNeuron, Oct 14, 2016
    Last edited: Oct 14, 2016

    AxoNeuron macrumors 65816

    AxoNeuron

    Joined:
    Apr 22, 2012
    Location:
    The Left Coast
    #4
    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
    
    
     
  5. AxoNeuron macrumors 65816

    AxoNeuron

    Joined:
    Apr 22, 2012
    Location:
    The Left Coast
    #6
    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.
     
  6. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #7
    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.
     
  7. AxoNeuron macrumors 65816

    AxoNeuron

    Joined:
    Apr 22, 2012
    Location:
    The Left Coast
    #8
    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!
     
  8. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #9
    Some smart guy about 30 years ago thought that up just so you could use it today.
     

Share This Page