Objective C, maze generation and 2D arrays - objective-c

I need to generate a random maze with given width and height. I could do this in Perl with Depth-first search algorithm, in which I use 2D arrays, something like this:
for my $i (0 .. $h - 1) {
for my $j (0 .. $w - 1) {
push #{ $cell[$i] }, '1';
}
push #{ $cell[$i] }, '0';
}
for my $i (0 .. $w) {
$cell[$h][$i] = '';
}
While in Objective C, there's no 2D array. I'm kind of lost now. What is the equivalent of 2D array in Objective C so that I pretty much can use the same data structure as in Perl?
Thanks.

One way is to use Objective-C style array:
NSMutableArray *cell = [NSMutableArray arrayWithCapacity:h];
for (int i=0; i<h; ++i) {
NSMutableArray *row = [NSMutableArray arrayWithCapacity:w];
for (int j=0; j<w; ++j) {
// use a random number
[row addObject:[NSNumber numberWithInt:rand()]];
}
// add one row
[cell addObject:row];
}
Another way is just to use C style array:
int **cell = malloc(h*sizeof(int *));
for (int i=0; i<h; ++i) {
cell[i] = malloc(w*sizeof(int));
for (int j=0; j<w; ++j) {
cell[i][j] = rand();
}
}
// after you used it remeber to free it
for (int i=0; i<h; ++i) {
free(cell[i]);
}
free(cell);
cell = NULL;

Use this github library to generate maze.
https://github.com/DoubleEqual/MazeGenerator-tool
The result looks like this for 24x24 maze:

A 2-Dimentional or N-Dimentional arrays are nothing but a way to store the data. If you want a 2-D array its fairly simple, but little bit tricky in obj-c, you have to creates 2nd level arrays, then insert it into first level.
See the code below :
NSMutableArray *twoDArray = [NSMutableArray new]; //this is first level
//below are second level arrays inserted in index 0 to 2.
[twoDArray insertObject:[NSMutableArray arrayWithObjects:#"00",#"01",#"02",nil] atIndex:0];
[twoDArray insertObject:[NSMutableArray arrayWithObjects:#"10",#"11",#"12",nil] atIndex:1];
[twoDArray insertObject:[NSMutableArray arrayWithObjects:#"20",#"21",#"22",nil] atIndex:2];

Related

Bucket Sort implementation in Objective C

I've been implementing different sorting algorithms in Objective-C (quicksort, mergesort, bubblesort). But I haven't found any clear implementation of Bucket Sort algorithm
I'm trying to find a simple and efficient implementation of Bucket Sort algorithm in objective C.
I ended up doing it my self, here's my implementation if anyone needs it:
- (NSArray*)bucketSort:(NSArray<NSNumber*> *)array buckets:(NSInteger)k {
// Initialize array of buckets
NSMutableArray<NSMutableArray*> *buckets = [NSMutableArray arrayWithCapacity:k];
for (int i=0; i < buckets.count; i++)
buckets[i] = [NSMutableArray new];
// Add elements to buckets
for (int i=0; i < buckets.count; i++) {
NSInteger index = k * array[i].floatValue; // Asuming "array" has values between 0 and 1
if (index < buckets.count) [buckets[index] addObject:array[i]];
}
NSMutableArray *sortedArray = [NSMutableArray new];
// Sort individual buckets
// Concatenate all sorted buckets in order
for (int i=0; i < buckets.count; i++) {
buckets[i] = [self quickSort:buckets[i]]; // Sorting algorithm like quicksort/mergesort/insertionsort
[sortedArray addObjectsFromArray:buckets[i]];
}
return sortedArray;
}

Objective C - Matrix Multiplication Slow Performance

I have 2 2-D NSMutableArrays and I am trying to do some basic matrix multiplication. I have my generic formula code below, but its performance is exceptionally slow (as expected). I have done lots of googling and have not found any easy nor easy to understand formulas to change up the code for performance enhancement. Can anyone point me in the right direction of a straightforward formula/tutorial/example of how to get better performance than 0(n^3) with matrix multiplication in Objective C.
+ (NSMutableArray*)multiply:(NSMutableArray*)a1 withArray:(NSMutableArray*)a2
{
if([[a1 objectAtIndex: 0] count] != [a2 count])
{
NSLog(#"Multiplicaton error!");
return NULL;
}
int a1_rowNum = [a1 count];
int a2_rowNum = [a2 count];
int a2_colNum = [[a2 objectAtIndex:0] count];
NSMutableArray *result = [NSMutableArray arrayWithCapacity:a1_rowNum];
for (int i = 0; i < a1_rowNum; i++) {
NSMutableArray *tempRow = [NSMutableArray arrayWithCapacity:a2_colNum];
for (int j = 0; j < a2_colNum; j++) {
double tempTotal = 0;
for (int k = 0; k < a2_rowNum; k++) {
double temp1 = [[[a1 objectAtIndex:i] objectAtIndex:k] doubleValue];
double temp2 = [[[a2 objectAtIndex:k] objectAtIndex:j] doubleValue];
tempTotal += temp1 * temp2;
}
//Stored as a string because I upload it to an online database for storage.
[tempRow addObject:[NSString stringWithFormat:#"%f",tempTotal]];
}
[result addObject:tempRow];
}
return result;
}
It will be much faster if you Write it in C.
double[] will be ridiculously fast compared to an NSArray of NSNumbers for this task. you'll have good cache coherency, minimal instructions, no need to go through the runtime or allocate in order to write or read an element. no need to perform reference count cycling on each element…
You need have a look at Apple's Accelerate frameWork for ios4.0 onwards.
You can do a lot of complex math and matrix manipulation with it and this framework is optimized to run on any iOS hardware.
Checkout:
https://developer.apple.com/performance/accelerateframework.html

How to cycle through an array of CGPoints

I have created an array of 16 CGpoints representing 16 positions on a game board. This is how i set up the array CGPoint cgpointarray[16]; I would like to create a for loop to cycle through each item in the array and check if the touch is within x distance of a position (i have the position as a CGPoint. I don't have much experiance with xcode or objective c. I know the python equivalent would be
for (i in cgpointarray){
//Stuff to do
}
How would i accomplish this? Thanks
for (int i = 0; i < 16; i++){
CGPoint p = cgpointarray[i];
//do something
}
Or if you want to use the NSArray Class:
NSMutableArray *points = [NSMutableArray array];
[points addObject:[ NSValue valueWithCGPoint:CGPointMake(1,2)]];
for(NSValue *v in points) {
CGPoint p = v.CGPointValue;
//do something
}
( not tested in XCode )
This should do it:
for (NSUInteger i=0; i < sizeof(cgpointarray)/sizeof(CGPoint); i++) {
CGPoint point = cgpointarray[i];
// Do stuff with point
}
I would normally go for the NSValue approach above but sometimes you are working with an API where you can't change the output. #Andrews approach is cool but I prefer the simplicity of .count:
NSArray* arrayOfStructyThings = [someAPI giveMeAnNSArrayOfStructs];
for (NSUInteger i = 0; i < arrayOfStructyThings.count; ++i) {
SomeOldStruct tr = arrayOfStructyThings[i];
.... do your worst here ...
}

Array of arrays with ints

How would you go about storing a 2 dimensional array of ints as a class variable?
If you want an array of ints you go:
Class declaration
int * myInts;
Implementation
int ints[3] = {1,2,3};
myInts = ints;
But what if you want to store an array of arrays with ints?
Like this:
int ints[3][3] = {{1,2,3}, {1,2,3}, {1,2,3}};
I don't wanna limit the size of the arrays in the class declaration so I guess I have to go with pointers, but how?
For future reference, this is my conclusion:
Class declaration
int ** ints;
Implementation
int rows = 2;
int cols = 5;
ints = (int**)malloc(rows*sizeof(int*));
ints[0] = (int*)malloc(cols*sizeof(int));
ints[0][0] = 123;
ints[0][1] = 456;
ints[0][2] = 789;
// etc
This is my own interpretation of links provided in comments and my C skills are pretty low so take that into consideration ;) Maybe there are better ways to put in multiple numbers at a time with {123,456,789} or something, but that is beyond my requirements for now!
I've wrote sample for you:
int N = 10, M = 15;
NSMutableArray *ints = [NSMutableArray arrayWithCapacity:N]; // array[N][M]
for (int i=0; i<N; i++)
{
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:M];
for (int j=0; j<M; j++)
{
[arr addObject:[NSNumber numberWithInt:(i+1)*(j+1)]];
}
[ints addObject:arr];
}
// print
for (int i=0; i<[ints count]; i++)
{
NSString *line = #"";
NSMutableArray *arr = [ints objectAtIndex:i];
for (int j=0; j<[arr count]; j++)
line = [NSString stringWithFormat:#"%# %#", line, [arr objectAtIndex:j]];
NSLog(#"%#", line);
}
If you want to dynamically allocate memory, in other words define the size of the arrays at runtime, then you need to declare the array as a pointer, malloc it, and then add another array of ints to each index at runtime. You can't really declare and dynamically allocate at the class level. If you are using cocoa/iphone sdk you can use NSMutableArray.
You could also create your own class that constructs a two dimensional array and exposes methods to push and pop int objects like [IntegerArray push:x,y,n];
Here's and example of using a double reference as Daniel R Hicks pointed out.

Array giving EXC_BAD_ACCESS in for loop

I have a C array defined in my method as:
int c = 4;
int r = 5;
keysArray[c][r];
I have this for loop, which works, populating the keysArray as expected.
for (int row = 0; row < r; row++) {
for (int column = 0; column < c; column++){
keysArray[column][row] = [anotherArray objectAtIndex:0];
NSLog(#"array1 %#",keysArray[column][row]);
[anotherArray removeObjectAtIndex:0];
}
}
Then in a for loop underneath, featuring exactly the same looping counter structure, when i try to NSLog the array, it gives an EXC_BAD_ACCESS.
for (int row = 0; row < r; row++){
for (int column = 0; column < c; column++) {
NSLog(#"array2: %#",keysArray[column][row]); //EXC_BAD_ACCESS here
}
}
What would cause this to happen, given that the keysArray is defined in the method body, outside of both sets of loops?
Are the contents of anotherArray retained by some other object? If not, they do not exist anymore in the second loop. WTH are you using a C array to store Objective-C objects anyway?
int c = 4;
int r = 5;
NSMutableArray *keysArray = [[NSMutableArray alloc] initWithCapacity:c];
for (int column = 0; column < c; column++) {
[keysArray addObject:[NSMutableArray arrayWithCapacity:r]];
for (int row = 0; row < r; row++) {
[[keysArray objectAtIndex:column] addObject:[anotherArray objectAtIndex:0]];
[anotherArray removeObjectAtIndex:0];
}
}
for (int row = 0; row < r; row++){
for (int column = 0; column < c; column++) {
NSLog(#"array2: %#", [[keysArray objectAtIndex:column] objectAtIndex:row]);
}
}
You need to retain the objects held in your C array. Unlikes an NS*Array, a C array does not retain on adding to the array.
However, for a no-holes 2D array like that, I'd just use a single NSMutableArray. Any N-dimensional array can be represented as a line-- as a one dimensional array-- with simple math.
Namely, to determine the index of an object at (X,Y), use (Y * width) + X).
The only caveat is that NS*Array does not support "holes". You will need to fill the array row by row. That is, for a 3x4 (3 wide, 4 tall) array, you would fill it in the order 0,0, 1,0, 2,0, 0,1, 1,1, etc...
Obviously, insert and remove operations will mess up your 2D representation (but they would in an NSMutableArray of NSMutableArrays, too).
Alternatively, use NSPointerArray as it can have holes.
Could this be the problem :
[anotherArray removeObjectAtIndex:0];
try
keysArray[column][row] = [[anotherArray objectAtIndex:0] retain];
although if I were you I would use NSMutableArray of NSMutableArray instead