Bucket Sort implementation in Objective C - 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;
}

Related

Objective C - Call Array objects in a random order [duplicate]

I'm using NSArray/NSMutable array to store different objects.
Once all the objects are added, I want to re-arrange them in random order.
How can I do it?
NSUInteger count = [yourMutableArray count];
for (NSUInteger i = 0; i < count; ++i) {
// Select a random element between i and end of array to swap with.
int nElements = count - i;
int n = (arc4random() % nElements) + i;
[yourMutableArray exchangeObjectAtIndex:i withObjectAtIndex:n];
}
// the Knuth shuffle
for (NSInteger i = array.count-1; i > 0; i--)
{
[array exchangeObjectAtIndex:i withObjectAtIndex:arc4random_uniform(i+1)];
}
Link GameplayKit/GameplayKit.h in your project then
#import <GameplayKit/GameplayKit.h>
Now you can use the property shuffledArray.
NSArray *randomArray = [yourArray shuffledArray];
Swift 4
let count = self.arrayOfData.count
for (index, _) in self.arrayOfData.enumerated()
{
let nTempElement = count - index
let swapIndexwith = (Int(arc4random()) % nTempElement) + index
arrayOfData.swapAt(index, swapIndexwith)
}

Objective C, maze generation and 2D arrays

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];

Force Shuffle NSMutableArray

I have a NSMutableArray called putNumberUsed. It contains the following objects #"blah1,#"blah2",#"blah3",#"blah4". I want to shuffle these objects randomly so for example if I chose:
[putNumberUsed objectAtIndex:0]
it would give me anything but "blah1". How would I go about doing this? The following is the code I used thus far:
NSMutableArray *putNumbersUsed = [[NSMutableArray alloc] arrayWithObjects:#"blah1",#"blah2",#"blah3",#"blah4",nil];
I think, You can write a loop for that. Please check the following code,
for (int i = 0; i < putNumberUsed.count; i++) {
int randomInt1 = arc4random() % [putNumberUsed count];
int randomInt2 = arc4random() % [putNumberUsed count];
[putNumberUsed exchangeObjectAtIndex:randomInt1 withObjectAtIndex:randomInt2];
}
I this this may be useful to you.
Here is a shuffling solution with all positions forced to change when count > 1.
Add a category like NSMutableArray+Shuffle.m:
#implementation NSMutableArray (Shuffle)
// Fisher-Yates shuffle variation with all positions forced to change
- (void)unstableShuffle
{
for (NSInteger i = self.count - 1; i > 0; i--)
// note: we use u_int32_t because `arc4random_uniform` doesn't support int64
[self exchangeObjectAtIndex:i withObjectAtIndex:arc4random_uniform((u_int32_t)i)];
}
#end
Then you can shuffle like:
[putNumbersUsed unstableShuffle];
This solution:
has no modulo bias
has no naive bias
has no sorting bias
A Swift 3.2 and Swift 4 equivalent is:
extension Array {
mutating func unstableShuffle() {
for i in stride(from: count - 1, to: 0, by: -1) {
swapAt(i, Int(arc4random_uniform(UInt32(i))))
}
}
}
A Swift 3.0 and 3.1 equivalent is:
extension Array {
mutating func unstableShuffle() {
for i in stride(from: count - 1, to: 0, by: -1) {
swap(&self[i], &self[Int(arc4random_uniform(UInt32(i)))])
}
}
}
Note: An algorithm for regular shuffling (where a result with same positions being possible) is also available
From iOS 10.x++ new concept of shuffle array is given by Apple,
You need to import the framework :
ObjeC
#import <GameplayKit/GameplayKit.h>
NSArray *shuffledArray = [yourArray shuffledArray];
Swift
import GameplayKit
let shuffledArray = yourArray.shuffled()
You can shuffle the object by using the following line of code,
[putNumbersUsed exchangeObjectAtIndex:3 withObjectAtIndex:0];
I think this may useful to you.
generate a random number for index
int randomInt = arc4random() % [putNumberUsed count];
[putNumberUsed objectAtIndex:randomInt];
Use this:
for (int i = 0; i < [putNumberUsed count]; i++) {
int random = arc4random() % [putNumberUsed count];
[putNumbersUsed exchangeObjectAtIndex:random withObjectAtIndex:i];
}

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.