Search code examples
iphoneobjective-ciosarc4random

iOS: How do I generate 8 unique random integers?


I need to generate 8 random integers, but they need to be unique, aka not repeated.

For example, I want 8 numbers within the range 1 to 8.

I've seen arc4random but I'm not sure how to make them unique ?

Solution

-(NSMutableArray *)getRandomInts:(int)amount from:(int)fromInt to:(int)toInt {

  if ((toInt - fromInt) +1 < amount) {
      return nil;    
  }

  NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
  int r;
  while ([uniqueNumbers count] < amount) {

      r = (arc4random() % toInt) + fromInt;
      if (![uniqueNumbers containsObject:[NSNumber numberWithInt:r]]) {
          [uniqueNumbers addObject:[NSNumber numberWithInt:r]];
      }
  }
  return uniqueNumbers;
}

Solution

  • -(NSMutableArray *)getEightRandom {
      NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
      int r;
      while ([uniqueNumbers count] < 8) {
        r = arc4random();
        if (![uniqueNumbers containsObject:[NSNumber numberWithInt:r]]) {
          [uniqueNumbers addObject:[NSNumber numberWithInt:r]];
        }
      }
      return uniqueNumbers;
    }
    

    If you want to restrict to numbers less than some threshold M, then you can do this by:

    -(NSMutableArray *)getEightRandomLessThan:(int)M {
      NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
      int r;
      while ([uniqueNumbers count] < 8) {
        r = arc4random() % M; // ADD 1 TO GET NUMBERS BETWEEN 1 AND M RATHER THAN 0 and M-1
        if (![uniqueNumbers containsObject:[NSNumber numberWithInt:r]]) {
          [uniqueNumbers addObject:[NSNumber numberWithInt:r]];
        }
      }
      return uniqueNumbers;
    }
    

    If M=8, or even if M is close to 8 (e.g. 9 or 10), then this takes a while and you can be more clever.

    -(NSMutableArray *)getEightRandomLessThan:(int)M {
      NSMutableArray *listOfNumbers = [[NSMutableArray alloc] init];
      for (int i=0 ; i<M ; ++i) {
        [listOfNumbers addObject:[NSNumber numberWithInt:i]]; // ADD 1 TO GET NUMBERS BETWEEN 1 AND M RATHER THAN 0 and M-1
      }
      NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
      int r;
      while ([uniqueNumbers count] < 8) {
        r = arc4random() % [listOfNumbers count];
        if (![uniqueNumbers containsObject:[listOfNumbers objectAtIndex:r]]) {
          [uniqueNumbers addObject:[listOfNumbers objectAtIndex:r]];
        }
      }
      [listOfNumbers release];
      return uniqueNumbers;
    }