Calling arc4random several times and getting the same array set - ios

I need a method to generate 4 numbers positioned randonly in an array. This method must be able to be called several times. The code that I tried below seems to be working.. except that everytime I call it, it generates the very same numbers sequence.
At my header file:
NSMutableSet * numberSet;
NSArray * numbers;
Code file:
numberSet = [NSMutableSet setWithCapacity:4];
[self placeRandomLine];
numbers = [numberSet allObjects];
... using the generated array
[self placeRandomLine];
numbers = [numberSet allObjects];
... using the generated array
[self placeRandomLine];
numbers = [numberSet allObjects];
... using the generated array
Random Method:
-(void)placeRandomLine
{
[numberSet removeAllObjects];
while ([numberSet count] < 4 ) {
NSNumber * randomNumber = [NSNumber numberWithInt:(arc4random() % 4)];
[numberSet addObject:randomNumber];
}
}
I am sure I am missing something here..
Thanks for your help!

Use an ordered set:
NSMutableOrderedSet *numberSet = [NSMutableOrderedSet new];
int setSize = 4;
while ([numberSet count] < setSize ) {
NSNumber * randomNumber = [NSNumber numberWithInt:arc4random_uniform(setSize)];
[numberSet addObject:randomNumber];
}
NSLog output:
numberSet: {(
2,
0,
1,
3
)}
Alternatively using an array or arbitrary numbers
Create an NSMutableArray with the four integers.
Create an empty NSMutableArray.
Use arc4random_uniform() to pick one of the numbers in the first array, remove it and place it in the second array.
Repeat for all four numbers.
The second array will have the four numbers in a random order.
Example:
NSMutableArray *a0 = [#[#3, #5, #4, #8] mutableCopy];
NSMutableArray *a1 = [NSMutableArray new];
while (a0.count) {
int randomIndex = arc4random_uniform(a0.count);
NSNumber *randomValue = a0[randomIndex];
[a1 addObject:randomValue];
[a0 removeObject:randomValue];
}
NSLog(#"a1: %#", a1);
NSLog output:
a1: (
8,
5,
3,
4
)
Alternatively using an ordered set

while ([numberSet count] < 4 ) will cause the loop to run until its elements are 0,1,2,3, because the set doesn't contain repeated elements.

Related

NSNumber in arrays, ios

I am trying to learn about how to put numbers into an array with nsnumber. The exact thing I'm stuck with is, To build the sequence in the array, we're going to need a loop. Between creating the sequence array and returning it, declare a for loop whose counter is limited by index + 1 and increments by one.
Since the sequence requires the two previous numbers to calculate the next one, we need to prime the sequence. We're going to need to manually pass in #0 and #1 on the first two iterations of the loop. This is what I have so far.
(NSArray *)arrayWithFibonacciSequenceToIndex:(NSUInteger)index
{
NSMutableArray *sequence = [NSMutableArray array];
for(NSUInteger i = 0; i < 1; i++)
{
index = i+1;
}
return sequence;
}
Am I on the right track? I'm not sure if my for loop is correct. Do I put sequence into the for loop and add the nsnumber #0 and #1 there or do I put those numbers into the sequence outside the loop?
To insert a number in an NSArray, you have to wrap them in a NSNumber:
NSInteger a = 5;
NSNumber number = #(a); // ou #5;
to perform mathematical operations on 2 NSNumbers, you have to convert them to integer (or double, float...) before
NSNumber * number1 = #1;
NSNumber * number2 = #6;
NSInteger sum = [number1 integerValue] + [number2 integerValue];
for the fib problem, youre loop is correct. The way I would think of this is : I add my value in the for loop, and if I'm adding the 1st or 2nd element, then I put a 0, else I sum the last 2 elements:
- (NSArray *) fibbonacciSequenceWithSize:(NSInteger)size
{
NSMutableArray * result = [NSMutableArray new];
for(NSInteger idx = 0; i < size ; i ++)
{
// first 2 numbers of fib sequence are 1
if(idx == 0 || idx == 1)
{
[result addObject:#1];
}
else
{
// Add the 2 previous number
// F2 = F1 + F0
NSinteger next = [result[idx - 2] integerValue] + [result[idx - 1] integerValue];
[result addObject:#(next)];
}
}
return [result copy]; // copy the NSMutableArray in a NSArray
}
You can clean up the code by having a Fibonacci function that provides the sum of the last two elements.
- (NSNumber *)nextFibInArray:(NSArray *)array {
if (array.count < 2) return #1;
NSInteger lastIndex = array.count - 1;
return #([array[lastIndex-1] intValue] + [array[lastIndex] intValue]);
}
Then the loop is cleaner, too.
- (NSArray *)fibonacciWithLength:(NSInteger)length {
NSMutableArray *result = [#[] mutableCopy];
for (NSInteger i=0; i<length; i++) {
[result addObject:[self nextFibInArray:result]];
}
return result;
}
We could trim some execution time fat from this, but for short enough sequences, this should be clear and quick enough.

How to save two Arrays in two dimensional Array?

I am new at iOS Dev. I want to save two different arrays (array1 & array2) in 2 dimensional array. I know how to save data directly in two dimensional array but can't by save two different arrays in one.
NSString* path = [[NSBundle mainBundle] pathForResource:#"Aasvogel" ofType:#"txt"];
NSString* content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];
NSArray* foo = [content componentsSeparatedByString: #","];
NSMutableArray *array1 = #[], *array2 = #[];
for ( int i = 0; i < [foo count]; i++ )
{
NSString* day = foo[i];
if ( i % 2 == 0 ) { [array1 addObject:day];}
else { [array2 addObject:day];}
}
// and here i have populated two arrays (array1 and array2)
// Now i want to save these arraya in below two dimensional array (dataArray) atIndex:0 and at Index:1
NSMutableArray *dataArray = [[NSMutableArray alloc] initWithCapacity: 2];
[dataArray addObject:[NSMutableArray arrayWithObjects:#"e",
#"el",
#"ale",
#"vela",
#"gavel",nil] atIndex:0];
[dataArray addObject:[NSMutableArray arrayWithObjects:#"Represents 50 in Roman numeral",
#"Building Wing",
#"Pub Brew",
#"Thin Parchment or membranes",
#"chairperson's hammer",nil] atIndex:1];
I have recently implemented 2D array into my application. Please check below code which is available at 2DArray
int capacity;
#property (nonatomic, strong) NSMutableArray *outerArray;
#define kCRL2DArrayEmptyKey #"kCRL2DArrayEmptyKey"
- (id) initWithRows:(int)x columns:(int)y
{
if (self = [super init])
{
capacity = y;
self.outerArray = [NSMutableArray array];
for (int i = 0; i < x; i++) {
NSMutableArray *innerArray = [NSMutableArray array];
for (int j = 0; j < y; j++) {
[innerArray addObject:kCRL2DArrayEmptyKey];
}
[self.outerArray addObject:innerArray];
}
}
return self;
}
you can try this
NSArray * firstArray, *secondArray;
NSArray * mainArray= [[NSArray alloc]initWithObjects: firstArray, secondArray, nil];
I am not sure about 2-dimensional array in iOS but if I were you I would be saved the two arrays within a dictionary such as
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
[dict setvalue:yourArray forKey:#"FirstArray"];
[dict setvalue:yourSecondArray forKey:#"SecondArray"];
And Use it accordingly.
There’s no such thing as a two (or more) dimensional NSArray. If you genuinely need an n-dimensional array object in iOS or OS X, you can of course roll your own, or you could instead create an NSArray of NSArray instances (which are columns and which are rows is entirely up to you). In that case, you could e.g. add items by doing
[[outerArray objectAtIndex:0] addObject:#"Foo"];
[[outerArray objectAtIndex:1] addObject:#"Bar"];
That said, for the problem you are tackling, it looks to me as if an NSDictionary might be more appropriate, e.g. with keys #"e", #"el" and values #"Represents 50 in Roman numerals", #"Building Wing".
If your concern is that the keys of NSDictionary are not held in sorted order, you can always extract the keys as an array and sort them. Or, if the keys change regularly, you might want to use a more sophisticated approach (e.g. keeping a separate sorted array of keys and inserting them into the right place when adding to the NSDictionary).
Also, you know that in modern Objective-C you can write e.g.
#[ #"a", #"b", #"c" ]
or
#{ #"a": #1, #"b": 2 }
rather than the very verbose forms you're using above?
this is how u add anything in a 2d array i.e an Array of arrays in objective-c
NSMutableArray *array 1 = [[NSMutableArray alloc]init];
NSMutableArray *array 2;
for(int col = 0;col <5;col++){
array2 = [[NSMutableArray alloc]init];
for(int row = 0;row<5;row++){
[array2 addObject:myItems];
}
[array1 addObject:array2];
}
hope this helps
use for loop to generate 2d array from 2 different array,
follow this stracture
int i, j;
for(i = 0; i < nrows; i++)
{
for(j = 0; j < ncolumns; j++)
array[i][j] = 0;
}
}
May be it will help you

How to find the average of a group of NSNumbers from NSMutableArray?

I have an NSMutableArray of NSNumbers that I have created using this code.
if (countMArray == nil) {
countMArray = [[NSMutableArray alloc] init];
}
if ([countMArray count] == 10) {
[countMArray removeObjectAtIndex:0];
}
NSNumber *currentX = [NSNumber numberWithDouble:x];
[countMArray addObject:currentX];
NSLog(#"%#", countMArray);
this is how my array looks.
2014-05-02 20:34:35.065 MotionGraphs[3721:60b] (
"0.0292816162109375",
"0.0315704345703125",
"0.03271484375",
"0.030517578125",
"0.03094482421875",
"0.0302886962890625",
"0.03192138671875",
"0.0306396484375",
"0.03094482421875",
"0.02874755859375"
)
I would like to find the average of the 10 numbers, I understand the mathematics behind it are simple: add all the values then divide by 10. However, I would like to know the best way to attempt this.
If you simply wanted to average all the countMArray in the numbers array, you could use KVC collection operator:
NSNumber *average = [countMArray valueForKeyPath:#"#avg.self"];
You should use if array contains NSNumber
NSNumber *average = [countMArray valueForKeyPath:#"#avg.doubleValue"];
But you are having NSStrings, so use this below method
-(double)avgOfArray:(NSArray*)array{
double total=0.0;
for (NSString *aString in array) {
total+=[aString doubleValue];
}
return ([array count]>0)?(total/[array count]):total;
}

display images randomly in 3 UIButton using single array content

I have created three UIButton and i have 11 images in an array. I want to display that images randomly in each and every buttons.
Edited
button2Image, button3Image, button4Image is NSString,
button2Image = [topButtonArray objectAtIndex:l1Counter];
NSArray *reversed = [[testArray reverseObjectEnumerator] allObjects];
button3Image = [topButtonArray objectAtIndex:nextCounter+1];
int random = arc4random_uniform([topButtonArray count]);
button4Image = [topButtonArray objectAtIndex:random];
Note: I don’t want to display same image in each button.
NSArray *urImageArray;//11 images
NSMutableArray *threeImages = [[NSMutableArray alloc]init];
while ([threeImages count]<3) {
id image=[urImageArray objectAtIndex:[self getRandomNumberBetween:0 maxNumber:11-1]];
// Three images must be different
if (![threeImages containsObject:image]) {
[threeImages addObject:image];
}
}
firstButtonImage = [threeImages objectAtIndex:0];
twoButtonImage = [threeImages objectAtIndex:1];
thirdButtonImage = [threeImages objectAtIndex:2];
- (NSInteger)getRandomNumberBetween:(NSInteger)min maxNumber:(NSInteger)max
{
return min + arc4random() % (max - min + 1);
}
If the question is how to pick random elements from array, here is a nice article with examples: http://nshipster.com/random/.
For example:
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
//i is number of required random elements
int i = 3;
while (i-->0)
{
if ([array count] > 0) {
int idx = arc4random_uniform([array count]);
[resultArray addObject:array[idx]];
//array is a mutable array whether the original one or it's deep copy
[array removeObjectAtIndex:idx];
}
}
For that you have to non-repeating random number. Then use that number to get the image from image array
arr123=[[NSMutableArray alloc]init];
int random = arc4random_uniform(11);
[arr123 addObject:[NSString stringWithFormat:#"%d",random]];
[self do1];
NSLog(#"%#",arr123);
int iMatch=0;
-(void)do1
{
int random = arc4random_uniform(11);
if([arr123 count]==2)
return;
for(int i=0;i<1;i++)
{
for(int j=0;j<[arr123 count];j++)
{
if(random==[[arr123 objectAtIndex:j] intValue])
{
iMatch=1;
break;
}
}
if(iMatch==1)
{
iMatch=0;
[self do1];
}
else
{
iMatch=0;
[arr123 addObject:[NSString stringWithFormat:#"%d",random]];
[self do1];
}
}
}
Then use the arr123 array to get the random images from image array using the random indexes
you should create an NSSet with the objects you get from the array. The NSSet has only distinct objects so you will add random objects from the array to the NSSet until the NSSet counts 3 objects. Look at apple NSSet documentation:
https://developer.apple.com/library/mac/documentation/cocoa/Reference/Foundation/Classes/NSSet_Class/Reference/Reference.html

converting a onedimensional array to 2-d array having the specified number of columns

i am passing one one dimensional array having elements "1,2,3,4,5,6,7"
and in my code i want to convert this array into a 2-dimensional array .
The number of columns of the 2-d array will be specified by user .
say if am setting the columns value to 3
then the output 2-d array should be in the format
123
456
7
.m file of my class
-(NSMutableArray *)OneToTwoDimensionalArray:(NSMutableArray *)values :(NSInteger)columns
{
NSMutableArray * twoDimensional=[[NSMutableArray alloc]initWithCapacity:columns];
for(int i=0;i<columns;i++)
{
[twoDimensional insertObject:values atIndex:i];
}
return twoDimensional;
}
viewcontroller.m file
EPArray *arr=[[EPArray alloc]init];
int columns=4;
arr1=[[NSMutableArray alloc]initWithObjects:#"1",#"2",#"3",#"4",#"5",#"6",#"7",nil];
NSMutableArray *finalresult=[arr OneToTwoDimensionalArray:arr1 :columns];
for(int i=0;i<columns;i++)
{
NSLog(#"%#",[finalresult objectAtIndex:i]);
}
Try this,
NSArray *array = #[#"1", #"2", #"3", #"4", #"5", #"6", #"7"];
int noOfColumns = 3;
NSMutableArray *outerArray = [[NSMutableArray alloc] init];
for (int counter = 0; counter < [array count]; counter = counter + noOfColumns) {
NSMutableArray *innerArray = [[NSMutableArray alloc] init];
for (int arrayIndex = counter; ((arrayIndex < counter + noOfColumns) && (arrayIndex < [array count])); arrayIndex++) {
[innerArray addObject:array[arrayIndex]];
}
[outerArray addObject:innerArray];
}
NSLog(#"outerArray = %#", outerArray);
Here outerArray will give the 2 dimensional array with the provided column value. The above code is readable and easy to maintain especially if you want to make some quick changes.
Output:
outerArray = (
(
1,
2,
3
),
(
4,
5,
6
),
(
7
)
)
Next to my other answer — that I would favor — I want to offer another solution, that uses more traditional C-style programming but is quite readable.
NSUInteger columnWidth = 3;
NSArray *array = #[#1, #2, #3, #4 ,#5, #6, #7];
NSMutableArray *newArray = [NSMutableArray array];
NSUInteger columnIdx = 0;
for (NSUInteger count = 0; count < [array count]; ++count) {
if (columnIdx == 0) {
[newArray addObject:[NSMutableArray array]];
}
NSMutableArray *lastArray = [newArray lastObject];
[lastArray addObject:array[count]];
columnIdx = (++columnIdx)%columnWidth;
}
newArray now contains the subarrays as required.
note, that also this solution uses the modulo operator columnIdx = (++columnIdx)%columnWidth;.
instead of this you also could write
++columnIdx;
if(columnIdx == columnWidth) columnIdx = 0;
NSUInteger columnWidth = 3;
NSArray *array = #[#1, #2, #3, #4 ,#5, #6, #7];
NSMutableArray *mArray =[NSMutableArray array];
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (idx % columnWidth == 0) {
[mArray addObject:[NSMutableArray array]];
}
[[mArray objectAtIndex:[mArray count]-1] addObject:obj];
}];
mArraynow contains 3 arrays with
(
(
1,
2,
3
)
,
(
4,
5,
6
)
,
(
7
)
)
This code uses the modulo operator that finds the remainder of division of one number by another.
if (idx % 3 == 0) {
[mArray addObject:[NSMutableArray array]];
}
if there is no remainder, it must be the index 0,3,6,…. In such a case, a new array is added to the outer array. the object are always added to the last array.
Also note that using enumerateObjectsUsingBlock: should be faster than using c-style for (for(int i=0;i<columns;i++)) or even fast enumeration.
I added a second answer that uses only C-constructs rather than blocks, but I'd favor this one.
and — of course — you should consider using a category on NSArray
#interface NSArray (Columns)
-(NSArray *)arrayOfArraysWithColumnWidth:(NSUInteger)width;
#end
#implementation NSArray (Columns)
-(NSArray *)arrayOfArraysWithColumnWidth:(NSUInteger)width
{
NSAssert(width > 0, #"width need to be 1 or greater");//sanity check
NSMutableArray *mArray =[NSMutableArray array];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (idx % width == 0) {
[mArray addObject:[NSMutableArray array]];
}
[[mArray objectAtIndex:[mArray count]-1] addObject:obj];
}];
return mArray;
}
#end
You would use it like:
NSArray *numbers = [#[#1, #2, #3, #4 ,#5, #6, #7] arrayOfArraysWithColumnWidth:3];

Resources