Objective-C equal distribution from 5 different NSMutableArrays - objective-c

This is my code but its still not correct. Currently i can distribute like this: 0,1,2,0,1,2,0,1,2 but i will distribute it 0,1,2,2,1,0,0,1,2,2 (0,1,2 are the groups)
//Create x Groups
for (int z=0; z<numberOfGroups; z++) {
mutableArrayOfSubarrays[z] = [NSMutableArray arrayWithCapacity:countOfElementsForTheGroups];
}
int nextSubarray = 0;
//Distribute the Objects into the groups
for (int i = 0; i < [AllObjectsToDistribute count]; i++)
{
[mutableArrayOfSubarrays[nextSubarray] addObject:[AllObjectsToDistribute objectAtIndex:i]];
nextSubarray = nextSubarray % customGroups;
nextSubarray++;
nextSubarray = nextSubarray % customGroups;
}

Keep track of which way the group index counts in a BOOL.
Example:
NSUInteger groupIndex = 0;
BOOL groupIndexCountsUp = YES;
for (id object in allObjectsToDistribute) {
[groupsArray[groupIndex] addObject:object];
if (groupIndexCountsUp) {
if (groupIndex < numberOfGroups - 1)
groupIndex++;
else
groupIndexCountsUp = NO;
}
else {
if (groupIndex > 0)
groupIndex--;
else
groupIndexCountsUp = YES;
}
}

Related

Finding consecutive integers in an Array

I am looking for an algorithm to determine if there are at least three consecutive numbers in an array. I have found several and tweaked them a bit, but it does not seem to be working. Below is what I am currently doing. The array is sorted using an NSSortDescriptor prior to the loop.
For example:
in an array [5,6,101,102,103] the three consecutive numbers are [101,102,103]
and the below function should return YES.
int c = [checkArray count];
int a,b = 0;
int cnt = 1;
for (int i = 1; i < c; i++)
{
a = [[checkArray objectAtIndex:i] intValue];
b = [[checkArray objectAtIndex:i-1] intValue] - 1;
if (a == b)
{
cnt++;
if (cnt == 3)
return YES;
} else {
cnt = 1;
}
}
return NO;
This is an alternative approach. I haven't tested it, but you should get the idea.
int c = [checkArray count];
int a,b,c = 0;
a = [[checkArray objectAtIndex:0] intValue];
b = [[checkArray objectAtIndex:1] intValue];
for (int i = 2; i < c; i++)
{
c = [[checkArray objectAtIndex:i] intValue];
if (a+2 == b+1 && b+1 == c)
return YES;
a = b;
b = c;
}
return NO;
It has the additional advantage of being easily optimized.
You should be able to do something like...
for (int i = 1; i < checkArray.count-1; i++)
{
int lower = [checkArray[i-1] intValue] +1;
int mid = [checkArray[i] intValue];
int upper = [checkArray[i+1] intValue] -1;
if (lower == mid && mid == upper) {
return YES;
}
}
return NO;
You only need to check each number once. No need to count anything. Each number you check is the middle of three numbers. If the one before and the one after are one less and one greater respectively then the three numbers are consecutive.

Detect break statement in function?

I have the function below:
- (void)doStuff {
BOOL allDoneNow = NO;
for (int i = 0; i < [arABFBmatches count]; i++) {
for (int j = 0; j < [arABFBmatches count]; j++) {
if (should_skip_rest) {
allDoneNow = YES;
break;
}
}
if (allDoneNow) break;
}
}
Now, if I call that method with [self doStuff];, how can I detect if the function broke? Or is there a better way to stop and restart the execution of a function?
- (BOOL)doStuff // <- return a boolean value
{
for (int i = 0; i < [arABFBmatches count]; i++)
{
for (int j = 0; j < [arABFBmatches count]; j++)
{
if (should_skip_rest)
{
return NO; // <- NO for break
}
}
}
return YES; // <- YES for completed
}
This beaks the execution of the function. If you want to restart it, simply call it in a while loop.
while( (doStuff()==NO) && thereShouldBeAnotherConditionForStopping )
{
// Do something after each attempt, otherwise it seems to be a little bit silly
}
Or you can use blocks, like this:
- (void)doStuff:(void (^)())breakBlock{
BOOL allDoneNow = NO;
for (int i = 0; i < [arABFBmatches count]; i++) {
for (int j = 0; j < [arABFBmatches count]; j++) {
if (should_skip_rest) {
allDoneNow = YES;
breakBlock();
break;
}
}
if (allDoneNow) breakBlock();
}
}
and call it:
[self doStuff:^{
NSLog(#"ends with break");
}];

Algorithm to find all possible solutions from an array of array

What is the best algorithm to find all possible words from an array of array of character.
Here an example :
From this array : [[A],[B,C,D],[E,F],[G,H]]
I need in return an array of the 12 ordered possibilities [[A,B,E,G],[A,C,E,G], ... , [A,D,F,H]]
Do you know how to implement this algorithm ? If you know it and you provide an example in any language (C,JAVA,Javascript, ...), feel free to share because it's been a day I try to find it ...
Here how I tries to implement it ("array" is an array of array of char):
+ (NSArray*) possibleReading:(NSMutableArray*)array {
int nbPossibilities = 1;
for(int i = 0; i < [array count]; i++) {
nbPossibilities *=[[array objectAtIndex:i] count];
}
NSMutableArray *possArr = [[NSMutableArray alloc] initWithCapacity:nbPossibilities];
for (int i=0; i < nbPossibilities; i++) {
NSMutableArray *innerArray = [[NSMutableArray alloc] initWithCapacity:[array count]];
[possArr addObject:innerArray];
}
for (int i=0; i< [array count]; i++) {
//
for(int nbPoss = 0; nbPoss < nbPossibilities; nbPoss++) {
NSMutableArray * arr = [possArr objectAtIndex:nbPoss];
NSNumber * num = [NSNumber numberWithInt:nbPoss % [[array objectAtIndex:i] count]];
NSString * literal = [[array objectAtIndex:i] objectAtIndex:[num intValue]];
[arr insertObject:literal atIndex:i];
}
}
return possArr;
}
It would be easiest to do this using a recursive method.
Java code
import java.util.Arrays;
public class CartesianProductCalculator {
private char[][] result;
private char[][] sets;
private char[] currentSet;
private int index;
public char[][] calculateProduct(char[][] sets) {
index = 0;
// calculate size of result
int resultSize = 1;
this.sets = sets;
for (char[] set : sets) {
resultSize *= set.length;
}
result = new char[resultSize][];
currentSet = new char[sets.length];
calculateProduct(sets.length-1);
return result;
}
// fills result from right to left
public void calculateProduct(int setIndex) {
if (setIndex >= 0) {
for (char c : sets[setIndex]) {
currentSet[setIndex] = c;
calculateProduct(setIndex-1);
}
} else {
result[index++] = Arrays.copyOf(currentSet, currentSet.length);
}
}
public static void main(String[] args) {
char[][] input = {{'A'},{'B','C','D'},{'E','F'},{'G','H'}};
CartesianProductCalculator productCalculator = new CartesianProductCalculator();
System.out.println(Arrays.deepToString(productCalculator.calculateProduct(input)));
}
}
Objectiv-C
+ (NSArray *) cartesianProductOfArrays(NSArray *arrays) {
int arraysCount = arrays.count;
unsigned long resultSize = 1;
for (NSArray *array in arrays)
resultSize *= array.count;
NSMutableArray *product = [NSMutableArray arrayWithCapacity:resultSize];
for (unsigned long i = 0; i < resultSize; ++i) {
NSMutableArray *cross = [NSMutableArray arrayWithCapacity:arraysCount];
[product addObject:cross];
unsigned long n = i;
for (NSArray *array in arrays) {
[cross addObject:[array objectAtIndex:n % array.count]];
n /= array.count;
}
}
return product;
}
C
#include <stdio.h>
#include <string.h>
void print(int size, char *array[size], int indexs[size]){
char result[size+1];
int i;
for(i = 0; i < size; ++i)
result[i] = array[i][indexs[i]];
result[size] = 0;
puts(result);
}
int countUp(int size, int indexs[size], int lens[size]){
int i = size -1;
while(i >= 0){
indexs[i] += 1;// count up
if(indexs[i] == lens[i])
indexs[i--] = 0;
else
break;
}
return i >= 0;
}
void find_all(int size, char *array[size]){
int lens[size];
int indexs[size];
int i;
for(i = 0; i < size; ++i){//initialize
lens[i] = strlen(array[i]);
indexs[i] = 0;
}
do{
print(size, array, indexs);
}while(countUp(size, indexs, lens));
}
int main(void){
char *array[] = { "A", "BCD", "EF", "GH" };
int size = sizeof(array)/sizeof(*array);
find_all(size, array);
return 0;
}
If you can remove duplicate entries in inner array objects before executing method then you won't get duplicate words in result array.
- (NSArray*) possibleReading:(NSMutableArray*)array {
int nbPossibilities = 1;
for(int i = 0; i < [array count]; i++)
{
NSArray *cleanedArray = [[NSSet setWithArray:[array objectAtIndex:i]] allObjects];
[array replaceObjectAtIndex:i withObject:cleanedArray];
nbPossibilities *=[[array objectAtIndex:i] count];
}
NSMutableArray *possArr = [[NSMutableArray alloc] initWithCapacity:nbPossibilities];
for (int i=0; i < nbPossibilities; i++) {
NSMutableArray *innerArray = [[NSMutableArray alloc] initWithCapacity:[array count]];
[possArr addObject:innerArray];
}
for (int i=0; i< [array count]; i++) {
//
for(int nbPoss = 0; nbPoss < nbPossibilities; nbPoss++) {
NSMutableArray * arr = [possArr objectAtIndex:nbPoss];
NSNumber * num = [NSNumber numberWithInt:nbPoss % [[array objectAtIndex:i] count]];
NSString * literal = [[array objectAtIndex:i] objectAtIndex:[num intValue]];
[arr insertObject:literal atIndex:i];
}
}
return possArr;
}

Generating primes List in objective C?

I create this objective C class to Genrate prime numbers from n to limit. I have problem I could not get the item in NSMutableArray inside for loop. can some one show me how can I fix it?
#implementation Prime
-(NSMutableArray *)generatePrimes:(int)upperLimit{
NSMutableArray *primes = [[NSMutableArray alloc]init];
bool isPrime;
int j;
[primes addObject:[NSDecimalNumber numberWithInt:2]];
for (int i= 3; i <= upperLimit ; i+=2) {
j = 0;
isPrime = YES;
NSInteger index;
for(id obj in primes)
{
index = [primes indexOfObject:obj];
if((index * index) <= i )
{
if(i % index == 0)
{
isPrime = NO;
break;
}
}
}
if(isPrime)
{
[primes addObject:[NSDecimalNumber numberWithInt:i]];
}
}
return primes;
}
#end
This question is a little vague, but it seems to me what you're trying to do is convert the NSDecimalNumber back into an int. What your code is actually doing is getting the number's index inside the array (ie the first object is 0, the second is 1, etc.) If you are trying to get the original value of i, change these lines:
for(id obj in primes)
{
index = [primes indexOfObject:obj];
to this:
for(NSDecimalNumber num in primes)
{
index = [num integerValue];
I'd also recommend using a different name than index, as that's misleading as to what you're actually doing.
-(NSMutableArray *)generatePrimes:(int)upperLimit
{
NSMutableArray *primes = [[NSMutableArray alloc]init];
bool isPrime;
for (int i=2; i<upperLimit; i++)
{
bool prime = true;
for (int j=2; j*j<=i; j++)
{
if (i % j == 0)
{
prime = false;
break;
}
}
if(prime)
{
[primes addObject:[NSDecimalNumber numberWithInt:i]];
}
}
return primes;
}
or
-(NSMutableArray *)generatePrimes:(int)upperLimit
{
NSMutableArray *primes = [[NSMutableArray alloc]init];
[primes addObject:[NSDecimalNumber numberWithInt:2]];
for(int i=3; i < upperLimit; i++)
{
bool prime=true;
for(int j=0;j<primes.count && (((NSDecimalNumber *)primes[j]).integerValue*((NSDecimalNumber *)primes[j]).integerValue) <= i;j++)
{
if(i % (((NSDecimalNumber *)primes[j]).integerValue) == 0)
{
prime=false;
break;
}
}
if(prime)
{
[primes addObject:[NSDecimalNumber numberWithInt:i]];
}
}
return primes;
}
Hope this helps!

Leak of Malloc 16 Bytes in C / Objective-C

When I profile my code with Instruments, it shows a leak of Malloc 16 bytes from this function (below), but I never used malloc in this function. Is there a place in this function where I should free some resources?
It may look like a lot of code, but there is really only the variables counts and counts2 as possible offenders I think.
+ (int) trimArray: (NSMutableArray*) source above: (short) max andMin: (short) min
{
int counts[6][7];
int counts2[6][7];
for (int i=0;i<=5;i++)
{
for (int ii=0;ii<7;ii++)
{
counts[i][ii] = 0;
counts2[i][ii] = 0;
}
}
int capacity = (int)[source count]/max;
if (capacity <2)
capacity = 2;
NSMutableArray *itemsToRemove = [[NSMutableArray alloc] initWithCapacity:capacity];
int week,dow,count1,count2;
EntryTimeItem *item;
NSEnumerator *e;
e = [source objectEnumerator];
while (item = [e nextObject])
{
week = item.week_number;
dow = item.day_of_the_week;
if (week >=0 && week <6 && dow >=0 && dow <7)
{
counts[week][dow]++;
}
}
e = [source objectEnumerator];
while (item = [e nextObject])
{
week = item.week_number;
dow = item.day_of_the_week;
if (week >= 0 && week < 6 && dow >= 0 && dow < 7)
{
count2 = counts2[week][dow];
count1 = counts[week][dow];
if (count1 > max)
{
if (!count2)
{
item.time = -1;
item.align = NSCenterTextAlignment;
item.label = [NSString stringWithFormat:#"%d entries",count1];
}
else {
// remove this item if it is after the first item which
// was converted to a placeholder for all the items
[itemsToRemove addObject:item];
}
}
counts2[week][dow]++;
}
}
e = [itemsToRemove objectEnumerator];
while (item = [e nextObject])
{
[source removeObject:item];
}
int count_extra_events = 0;
for (int i=0;i<7;i++)
{
int count_events2 = 0;
for (int ii = 0; ii < 6; ii++)
{
int count3 = counts[ii][i];
if (count3 < max && count3 > min)
count_events2 += count3 - min;
}
// store the greatest value found sofar
if (count_events2 > count_extra_events)
{
count_extra_events = count_events2;
}
}
return count_extra_events;
}
The problem appears to stem from the line:
NSMutableArray *itemsToRemove = [[NSMutableArray alloc] initWithCapacity:capacity];
Please check if there is anyway, the resource itemsToRemove can be freed.