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];
}
Related
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;
}
Question:
Find the value of K in myInterViewArray without any messages/calls
I was given this hint:
The numbers in the array will never exceed 1-9.
NSArray *myInterViewArray = #[#2,#1,#3,#9,#9,#8,#7];
Example:
If you send 3, the array will return the 3 biggest values in myInterViewArray * 3. So in the example below, K = 9 + 9 + 8.
--
I was asked this question a while back in an interview and was completely stumped. The first solution that I could think of looked something like this:
Interview Test Array:
[self findingK:myInterViewArray abc:3];
-(int)findingK:(NSArray *)myArray abc:(int)k{ // With Reverse Object Enumerator
myArray = [[[myArray sortedArrayUsingSelector:#selector(compare:)] reverseObjectEnumerator] allObjects];
int tempA = 0;
for (int i = 0; i < k; i++) {
tempA += [[myArray objectAtIndex:i] intValue];
}
k = tempA;
return k;
}
But apparently that was a big no-no. They wanted me to find the value of K without using any messages. That means that I was unable to use sortedArrayUsingSelector and even reverseObjectEnumerator.
Now to the point!
I've been thinking about this for quite a while and I still can't think of an approach without messages. Does anyone have any ideas?
There is only one way to do that and that is bridging the array to CF type and then use plain C, e.g.:
NSArray *array = #[#1, #2, #3];
CFArrayRef cfArray = (__bridge CFArrayRef)(array);
NSLog(#"%#", CFArrayGetValueAtIndex(cfArray, 0));
However, if the value is a NSNumber, you will still need messages to access its numeric value.
Most likely the authors of the question didn't have a very good knowledge of the concept of messages. Maybe they thought that subscripting and property access were not messages or something else.
Using objects in Obj-C without messages is impossible. Every property access, every method call, every method initialization is done using messages.
Rereading the question, they probably wanted you to implement the algorithm without using library functions, e.g. sort (e.g. you could implement a K-heap and use that heap to find the K highest numbers in a for iteration).
I assume what is meant is that you can't mutate the original array. Otherwise, that restriction doesn't make sense.
Here's something that might work:
NSMutableArray *a = [NSMutableArray array];
for (NSNumber *num in array) {
BOOL shouldAdd = NO;
for (int i = a.count - 1; i >= k; i--) {
if ([a[i] intValue] < [num intValue]) {
shouldAdd = YES;
break;
}
}
if (shouldAdd) {
[a addObject:num];
}
}
int result = a[a.count - k];
for (int i = k; k < a.count; k++) {
result += [a[i] intValue];
}
return result;
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)
}
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];
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 ...
}