Random number generation from an NSMutable array [duplicate] - iphone

This question already has answers here:
Non repeating random numbers in Objective-C
(6 answers)
Generating non-repeating random numbers
(5 answers)
Closed 9 years ago.
I need to generate random numbers from an array i have tried this inside the for loop
rnd = arc4random_uniform(arr.count);
it generated random numbers but some numbers get repeated also tried Random() in math.h
still the same problem persists please help me out..
Thanks in advance..

if i understood
"I need to generate random numbers from an array"
correctly, you want the numbers to be taken from an array randomly, if so then
first store the numbers in an NSMutableArray
NSMutableArray *arr=//store your numbers in this array.
-(void)getRandomNumberFromArray:(NSMutableArray *)arr{
int r = arc4random() % arr.count;
int number=[arr objectAtIndex:r];
[arr removeObjectAtIndex:r];
}

Generate a random number for each element, and then check to make sure it's not the same as one of the existing ones. If it already exists, try again.
for(int i = 0; i < arr.count;i++)
{
BOOL isRandom = YES;
int rand = -1;
while(!isRandom )
(
isRandom = YES;
rand = arc4random() % 5;
for(int j = 0; j < i; j++)
{
int existingNumber = arr[j];
if(existingNumber == rand)
{
isRandom = NO;
break;
}
}
}
arr[i] = rand;
}
Another option is to first just assign them to have incrementing values, and then shuffle the mutable array. What's the Best Way to Shuffle an NSMutableArray?

If I understood your problem , then you dont need random numbers , you need to shuffle the elements in the Array ?
Then you need to use this method ,
-(void)shuffleWithArray:(NSArray*)cardsArray
{
NSMutableArray *shuffleArray =[[NSMutableArray alloc]initWithArray:cardsArray];
// NSUInteger count1=[shuffleArray count];
for (NSUInteger i= 0; i<[shuffleArray count]; i++)
{
int nElement=[shuffleArray count] -i;
int n=(arc4random()%nElement + i);
[shuffleArray exchangeObjectAtIndex:i withObjectAtIndex:n];
}
}

You can make use of the following function.
#property (nonatomic,strong) NSMutableArray * numbers;
- (NSInteger) nonRepeatedNumber
{
if(_numbers == nil)
{
_numbers = [[NSMutableArray alloc]init];
}
NSInteger number = arc4random()% arr.count;
while ([_numbers containsObject:[NSNumber numberWithInt:number]])
{
number = arc4random()% arr.count;;
}
[_numbers addObject:[NSNumber numberWithInt:number]];
return number;
}

Check the below Tutorial. it must help for you.
iOS Random Number generator

Try the following method
-(NSMutableArray*)randomNumbersfromArray:(NSArray*)array {
NSArray *numbers = array;
int count = [numbers count];
NSMutableArray *addedIndexes = [[NSMutableArray alloc]initWithCapacity:count];
NSMutableArray *addedObjects = [[NSMutableArray alloc]initWithCapacity:count];
int i = 0;
while ([addedIndexes count] != [numbers count]) {
int random = arc4random() % count ;
if (![addedIndexes containsObject:[NSString stringWithFormat:#"%i",random]]) {
[addedIndexes addObject:[NSString stringWithFormat:#"%i",random]];
[addedObjects addObject:[numbers objectAtIndex:random]];
i++;
}
}
return addedObjects;
}

#include <stdlib.h>
int r = 0;
if (arc4random_uniform != NULL)
r = arc4random_uniform (arr.count);
else
r = (arc4random() % arr.count);
int randomNumberFromArray=[arr objectAtIndex:r];
EDIT
Bingo.After some thinking i made it working
-(NSArray *)randomizeArray:(NSArray *)inputArray
{
NSMutableArray *checkArray=[[NSMutableArray alloc]initWithCapacity:3];
NSMutableArray *outputArray=[[NSMutableArray alloc]initWithCapacity:3];
while ([outputArray count]<[inputArray count])
{
int r=[self getRandomNumber:[inputArray count]];
if ([checkArray containsObject:[NSNumber numberWithInt:r]])
{
}
else
{
[checkArray addObject:[NSNumber numberWithInt:r]];
[outputArray addObject:[inputArray objectAtIndex:r]];
}
}
return outputArray;
}
-(int)getRandomNumber:(int)maxValue
{
int r = 0;
if (arc4random_uniform != NULL)
r = arc4random_uniform (maxValue);
else
r = (arc4random() % maxValue);
return r;
}
This randomizeArray: method will give you the whole array randomized

Related

shuffle array repeats One value

Here i used the following code to shuffle the NSMuttable Array, While shuffling The array repeats only one value and remaining all works properly, what change should i made to shuffle without repeating?
words = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3",#"4", nil] ;
NSUInteger count = [words count];
for (int i = 0; i < count; i++)
{
NSInteger nElements = count - i;
NSInteger n = (arc4random() % nElements) + i;
NSLog(#"n val %d i val %d",i,n);
[words exchangeObjectAtIndex:i withObjectAtIndex:n];
}
NSlog Output
2012-12-31 12:49:05.730 quizer[1607:c07] n val 0 i val 0
2012-12-31 12:49:05.731 quizer[1607:c07] n val 1 i val 3
2012-12-31 12:49:05.731 quizer[1607:c07] n val 2 i val 2
2012-12-31 12:49:05.732 quizer[1607:c07] n val 3 i val 3
Please Help me to solve
This code may help you,
The shuffle array contains each number between 0 to TOTAL_NUMBER (your array size) only once.
From which you can shuffle your existing array.
#synthesize alreadyGeneratedNumbers;//this is a mutableArray.
int TOTAL_NUMBER=5;//size of array
-(int)generateRandomNumber{
int low_bound = 0;
int high_bound = TOTAL_NUMBER;
int width = high_bound - low_bound;
int randomNumber = low_bound + arc4random() % width;
return randomNumber;
}
-(IBAction)randomNumbers:(UIButton *)sender
{
NSMutableArray *startArray=[NSMutableArray arrayWithObjects:#"1",#"2",#"3",#"4",#"5", nil];
NSMutableArray *shuffle = [NSMutableArray new];
BOOL contains=YES;
while ([shuffle count]<5) {
NSNumber *generatedNumber=[NSNumber numberWithInt:[self generateRandomNumber]];
//NSLog(#"->%#",generatedNumber);
if (![alreadyGeneratedNumbers containsObject:generatedNumber]) {
[shuffle addObject:generatedNumber];
contains=NO;
[alreadyGeneratedNumbers addObject:generatedNumber];
}
}
if ([alreadyGeneratedNumbers count] >= TOTAL_NUMBER) {
NSLog(#"\nOne shuffel ended.....what to reshuffle");
[alreadyGeneratedNumbers removeAllObjects];
}
NSMutableArray *shuffledArray=[NSMutableArray new];
for (NSNumber *index in shuffle) {
[shuffledArray addObject:[startArray objectAtIndex:[index integerValue]]];
}
NSLog(#"Shuffled array = %#",shuffledArray);
}
To remove duplicates from your NSMutableArray,
// Removing duplicate entry from array
NSArray *copy = [words copy];
NSInteger index = [copy count] - 1;
for (id object in [copy reverseObjectEnumerator])
{
if ([words indexOfObject:object inRange:NSMakeRange(0, index)] != NSNotFound)
{
[words removeObjectAtIndex:index];
}
index--;
}
[copy release];
You can check it for each time you add the object.

Want to generate non repeating random numbers [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Generating non-repeating random numbers
Here is my code
NSUInteger count = 10;
for (NSUInteger i = 0; i < count; ++i) {
NSLog(#"%d",NeedRandomNumberWithoutRepeat);
}
this output should be like
8
7
9
2
1
4
6
3
5
0
Which is random and not repeating numbers
This should work:
NSUInteger count = 10;
NSMutableArray *array = [[NSMutableArray alloc]init];
for (NSUInteger i = 0; i < count; ++i) {
[array addObject:[NSNumber numberWithInt:i]];
}
NSMutableArray *copy = [array mutableCopy];
array = [[NSMutableArray alloc]init];
while ([copy count] > 0)
{
int index = arc4random() % [copy count];
id objectToMove = [copy objectAtIndex:index];
[array addObject:objectToMove];
[copy removeObjectAtIndex:index];
}
This answer is modified version from one of my answer in SO.
So, you may find something strange here, you can however use this as your requirement is similar.
int TOTAL_NUMBER=10;
NSMutableArray *alreadyGeneratedNumbers;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
alreadyGeneratedNumbers=[NSMutableArray new];
}
-(int)generateRandomNumber{
int low_bound = 0;
int high_bound = TOTAL_NUMBER;
int width = high_bound - low_bound;
int randomNumber = low_bound + arc4random() % width;
return randomNumber;
}
- (IBAction)button:(id)sender {
NSMutableArray *shuffle = [[NSMutableArray alloc] initWithCapacity:1];
BOOL contains=YES;
while ([shuffle count]<1) {
NSNumber *generatedNumber=[NSNumber numberWithInt:[self generateRandomNumber]];
if (![alreadyGeneratedNumbers containsObject:generatedNumber]) {
[shuffle addObject:generatedNumber];
contains=NO;
[alreadyGeneratedNumbers addObject:generatedNumber];
}
}
NSLog(#"shuffle %#",shuffle);
NSLog(#"Next Batch");
if ([alreadyGeneratedNumbers count] >= TOTAL_NUMBER) {
NSLog(#"\nGame over, Want to play once again?");//or similar kind of thing.
[alreadyGeneratedNumbers removeAllObjects];
}
}
You put the available numbers in an array, and take the index calculated with arc4random() that goes from 0 to the size of the array -1.When a number comes out you take it away from the array:
NSMutableArray* availableNumbers=[NSMutableArray new];
for(NSUInteger i=0; i<10; i++)
{
[availableNumbers addObject: #(i)];
}
for(NSUInteger i=0; i<10; i++)
{
NSUInteger index= arc4random()%availableNumbers.count;
NSNumber* number= availableNumbers[index];
NSLog(#"%#",number);
[availableNumbers removeObjectAtIndex: index];
}
PS: At the last iteration is useless to sue arc4random(), since there's only one number inside.

Generating a unique number [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I'm trying to generate a unique number for a bingo app, now its choses at 90 random numbers between 1-90 and adds them to a NSMutableSet. That all works, but I get the number picked from the set to be unique, so the same number is pulled out twice.
Here is what I have so far:
NSMutableSet * numberSet1 = [NSMutableSet setWithCapacity:90];
while ([numberSet1 count] < 90 ) {
NSNumber * randomNumber1 = [NSNumber numberWithInt:(arc4random() % 90 + 1)];
[numberSet1 addObject:randomNumber1];
}
//NSLog(#"numberWithSet : %# \n\n",numberSet1);
NSArray * numbers = [numberSet1 allObjects];
//to display
int r = arc4random() % [numbers count];
if(r<[numbers count]){
numberLabel.text = [NSString stringWithFormat:#"%#", [numbers objectAtIndex:r]];
}
How can I stop it from giving me duplicates?
Thanks in advance
As an alternative to picking random numbers with arc4random() (which samples with replacement, which you probably don't want for a Bingo game):
Take an array of numbers 1 through 90.
Shuffle that array.
Pick the first number from the array, then the second, and so on.
Keep an index of the currently selected element in the array. To get the next number, increment and check if you are dereferencing the 90th element.
Some pseudo-code:
#define SIZE 90
unsigned int index;
unsigned int elements[SIZE];
/* step 1 -- populate the array with elements 1 through 90 */
for (index = 0; index < SIZE; index++)
elements[index] = index + 1;
/* step 2 -- shuffle the array */
fisher_yates_shuffle(elements);
/* step 3 -- read from the array */
for (index = 0; index < SIZE; index++)
fprintf(stdout, "element at index %u is %u\n", index, elements[index]);
This creates and shuffles an array.
// array to shuffle
NSMutableArray *array = [NSMutableArray array];
for(int i=1; i<91; i++){
[array addObject:[NSNumber numberWithInt:i]];
}
// shuffle
for (int i = [array count]-1; i>0; i--) {
[array exchangeObjectAtIndex:i withObjectAtIndex:arc4random()%(i+1)];
}
Not sure if this is what you want since picking 90 numbers at random from 1-90 with no duplicates and adding them to a mutable set is no different from adding everything to a mutable set. But if you want a subset of the 90 numbers just take up to n elements from the array.
From a lottery app I wrote a while back, also applicable here-
int ball[6], counter, check, similarity;
for ( counter = 1; counter <= 6; counter++ )
{
for (;;)
{
similarity = 0;
ball[counter] = 1 + arc4random() % 6;
for (check = counter-1; check >= 1;check--)
{
if ( ball[check] == ball[counter] )
{
similarity = 1;
break;
}
}
if(similarity == 0)
break;
}
printf("%i\n", ball[counter]);
}
Checks the chosen ball with all previous balls, will never get the same number twice.
Create a category on NSMutableArray
#implementation NSMutableArray (RandomUtils)
-(void)shuffle
{
NSUInteger count = [self count];
for (NSUInteger i = 0; i < count; ++i) {
NSUInteger nElements = count - i;
NSUInteger n = (arc4random() % nElements) + i;
[self exchangeObjectAtIndex:i withObjectAtIndex:n];
}
}
#end
You can also wrap it for a NSArray version
#implementation NSArray (RandomUtils)
-(NSMutableArray *)mutableArrayShuffled
{
NSMutableArray *array = [[self mutableCopy] autorelease];
[array shuffle];
return array;
}
-(NSArray *)arrayShuffled
{
return [NSArray arrayWithArray:[self mutableArrayShuffled]];
}
#end
Where needed, import the category, and do:
NSMutableArray *array = [NSMutableArray array];
for(int i=0; i<90; i++){
[array addObject:[NSNumber numberWithInt:i+1]];
}
[array shuffle];
NSArray *newarray = [array subarrayWithRange:NSMakeRange(0,6)];
Another approach could be to fill a set with 6 random picks.
in the Category:
#implementation NSArray (RandomUtils)
-(id)randomElement
{
if ([self count] < 1) return nil;
NSUInteger randomIndex = arc4random() % [self count];
return [self objectAtIndex:randomIndex];
}
#end
use it like:
NSMutableSet *mset = [NSMutableSet set];
while ([mset count]<6) {
[mset addObject:[array randomElement]];
}

How to check unique int number in iphone

How can we check if the number generated through
I am trying to generate a unique number in between 0 to 10.
randomNumber = arc4random() % 10;
is unique or not??
i am able to generate a random number, but not able to check,whether its unique or not?
Thanks
To avoid duplication, refer a following random number generation code. When you run the following code also does not overlap any number. If you mean you want it unique.
#define COUNT 1000
#define RANGE 1000
int num[COUNT];
bool isNew(int idx, int val)
{
for (int i=0; i<idx; i++)
{
if (num[i] == val) return false;
}
return true;
}
for (int i=0; i<COUNT; i++)
{
do
{
num[i]=arc4random()%RANGE;
}
while (!isNew(i, num[i]));
NSLog(#"%d ", num[i]);
}
You can save all generated numbers in an array and check whether there are two duplicates.
The more number you have, the more is sure that the generated numbers are unique.
Try this code...this will give you all the possible unique number set in Mutable array...
-(NSInteger) randomNumber {
NSInteger newRandomNumber = (NSInteger) arc4random() % 10;
NSInteger uniqueNumber;
if ([self.arrayContainingNumbers containsObject: [NSNumber numberWithInteger:newRandomNumber]]) {
[self randomNumber];
} else {
[self.arrayContainingNumbers addObject: [NSNumber numberWithInteger:newRandomNumber]];
}
uniqueNumber = [[self.mutableArrayContainingNumbers lastObject]integerValue];
NSLog(#"new Unique Number is %ld",(long)uniqueNumber);
return uniqueNumber; }
Don't forget to add this method :)
-(NSMutableArray *) arrayContainingNumbers {
if (!_mutableArrayContainingNumbers) {
_mutableArrayContainingNumbers = [[NSMutableArray alloc] init];
}
return _mutableArrayContainingNumbers; }

Random numbers without repetition

I am making Quiz app in which i want to generate random numbers without repetition.
I have searched many things and got the idea but i think i am doing something wrong that's why not getting correct output.
Here is the code that i used.
-(int)generater{
NSMutableArray *temp;
srand([[NSDate date] timeIntervalSince1970]);
r = 1 + (arc4random() % 11);
if ([temp count] ==0) {
[temp addObject:[NSNumber numberWithInteger:questionnumber]];
return r;
}
if ([temp count] >= 1 ){
if (![temp containsObject:[NSNumber numberWithInteger:questionnumber]]) {
return r;
}
else{
int next=[self generater];
return next;
}
}
return r;
}
For next Question,
-(void)askQuestion{
[self generater];
questionnumber = r;
NSInteger row = 0;
if(questionnumber == 1)
{
row = questionnumber - 1;
}
else
{
row = ((questionnumber - 1) * 11);
}
Can any one suggest me where i am wrong ?
arryRandomNumber=[[NSMutableArray alloc]init];
while (arryRandomNumber.count<12) {
NSInteger randomNumber=1+arc4random()%12;
if (![arryRandomNumber containsObject:[NSString stringWithFormat:#"%d",randomNumber]]) {
[arryRandomNumber addObject:[NSString stringWithFormat:#"%d",randomNumber]];
}
continue;
}
NSLog(#"%#",arryRandomNumber);
Surely the best approach is to put all the questions (or question numbers) sequentially into an array, and then shuffle them.
See What's the Best Way to Shuffle an NSMutableArray?
Some additional guidance (NB all code written in the browser and not actually compiled and tested; but should still get the gist):
1) Set up an ivar NSMutableArray *randomQuestionNumbers. Initialise the contents of the array with the number of questions, so if you have 5 questions put the numbers 1-5 in. To do it manually it would be:
randomQuestionNumbers = [NSMutableArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithInt:2], [NSNumber numberWithInt:3], [NSNumber numberWithInt:4], [NSNumber numberWithInt:5], nil];
2) After that, you need to shuffle, by using one of the methods given in the link above.
That will transform [1,2,3,4,5] -> [4,1,5,3,2] for example
3) So now create your method to get the next question number:
- (NSInteger) nextQuestionNumber {
NSInteger nextQuestionNumber = -1;
if ([randomQuestionNumbers count] > 0) {
nextQuestionNumber = (NSInteger) [randomQuestionNumbers objectAtIndex:0];
[randomQuestionNumbers removeObjectAtIndex:0];
}
return nextQuestionNumber;
}
What's happening here is we retrieve the first int in the array. Then we remove that element from the array. Finally, we return the int, e.g., 4. The next time the method is called, there is one fewer element, and the first element is the int 1, and so on. I'm rather crudely using -1 to show when the array is empty, but to be honest you should be able to ensure you don't call the method more times that necessary.
Hope this code will help you...
Here limit should be set by your requirement.
Benefit of this code is it won't repeat the same random number which is already been got. (No repetitive numbers)
srand(time(NULL));
int randomIndex = rand() % limit;
[reportIDTextField setText:[NSString stringWithFormat:#"%i", randomIndex]];
Enjoy coding :)
Random number between two numbers method:
- (int)randomFromSmallest: (int) smallest toLargest: (int) largest
{
int random = smallest + arc4random() % (largest + 1 - smallest);
return random;
}
And that's how I filling an array of non-repeating numbers:
NSMutableArray *randNrArray = [[NSMutableArray alloc] init];
while ([randNrArray count] < 25)
{
int rndNumber = [self randomFromSmallest:0 toLargest:25 - 1];
if (![randNrArray containsObject:[NSNumber numberWithInt:rndNumber]])
{
[randNrArray addObject:[NSNumber numberWithInt:rndNumber]];
//NSLog(#"___ %d ___", rndNumber);
}
}
I hope this helps.
Put all your question numbers in a NSMutableArray (1, 2, 3, 4, 5, 6, 7, 8), then perform a number of permutations on this array.
I use this approach to scramble a numeric keypad:
// Randomize keys: exchange two random keys, ten times.
for (int i = 0; i < 10; i++)
{
int a = 0, b = 0;
while (a == b)
{
a = arc4random() % 10;
b = arc4random() % 10;
}
UIButton *btnA = (UIButton *)[_scrambledKeypad viewWithTag:a + 10];
UIButton *btnB = (UIButton *)[_scrambledKeypad viewWithTag:b + 10];
CGRect frame = btnA.frame;
btnA.frame = btnB.frame;
btnB.frame = frame;
}
Maybe :
r = [self generater];
questionnumber = r;