Objective-C – Transform an array of numbers to arrays with numbers in sequence - objective-c

Is there an easy way to transform an array of numbers to an arrays with the numbers in sequence?
NSArray *numbers = #[#1,#2,#5,#3];
// Transformed arrays
//NSArray *numbersInSequence = #[#1,#2,#3];
//NSArray *numbersInSequence2 = #[#5];
EDIT:
I modified the code in Richard's answer to get it to work.
NSArray *arraysBySplittingNumbersInOrder(NSArray *input) {
// sort 'input'
input = [input sortedArrayUsingSelector:#selector(compare:)];
NSMutableArray *results = [NSMutableArray array];
if (input.count) {
int start = 0;
int last = INT_MIN;
for (int i = 0; i < input.count; i++) {
BOOL lastItem = i == input.count - 1;
// The first item of the array
if (i == 0) {
if (lastItem) {
[results addObject:input];
break;
}
last = [input[i] intValue];
continue;
}
int cur = [input[i] intValue];
if (cur != last + 1) {
// pull out the next array
[results addObject:[input subarrayWithRange:NSMakeRange(start, i - start)]];
start = i;
}
// The last item of the array
if (lastItem) {
[results addObject:[input subarrayWithRange:NSMakeRange(start, i - start + 1)]];
}
last = cur;
}
}
return results;
}

Here's a rather simple solution:
NSArray *arraysBySplittingNumbersInOrder(NSArray *input)
{
// sort 'input'
input = [input sortedArrayUsingSelector:#selector(compare:)];
NSMutableArray *results = [NSMutableArray array];
if (input.count)
{
int start = 0;
int last = INT_MIN;
for (int i = 0; i <= input.count; i++)
{
if (i == 0)
{
last = [input[i] intValue];
continue;
}
if (i == input.count)
{
if (i != start + 1)
{
[results addObject:[input subarrayWithRange:NSMakeRange(start, i - start)]];
continue;
}
}
int cur = [input[i] intValue];
if (cur != last + 1)
{
// pull out the next array
[results addObject:[input subarrayWithRange:NSMakeRange(start, i - start)]];
start = i;
}
last = cur;
}
}
return results;
}
int main()
{
NSArray *input = #[ #1, #3, #4, #7, #8, #12, #13, #14 ];
NSLog(#"%#", input);
NSLog(#"%#", arraysBySplittingNumbersInOrder(input));
}
Output:
2012-11-27 07:55:04.609 TestProj[35890:303] (
1,
3,
4,
7,
8,
12,
13,
14
)
2012-11-27 07:55:04.611 TestProj[35890:303] (
(
1
),
(
3,
4
),
(
7,
8
),
(
12,
13,
14
)
)

I don't think there's an easy way to do this; you'll probably have to do at least part of the work yourself.
My suggestion would be to sort the array an then iterate through it, building the sections as you go. Whenever you hit a "jump", i.e. a non-consecutive number, this concludes your current section and starts a new one.

Related

How to save multiple small integers in one integer via bit shifting in Objective C

There are several lists of items. The number of the lists < 8. The number of items in any list < 16. User can select one item in each list. So we have a sequence of integers. For example: 9, 0, 12, 4.
There are any easy way to store user selection in one Integer (32 or 64) and reading it from there?
May be you know the more optimal way to store a sequence of 4-bit integers?
Thanks!
+ (NSArray *)arrayFromLongint:(uint32_t)longint {
uint8_t shortint;
NSMutableArray *array = [[NSMutableArray alloc] init];
for (uint8_t i = 0; i < 32; i = i + 4) {
shortint = longint >> i & 15; // 15 is 00001111 in binary
[array addObject:[NSNumber numberWithUnsignedShort:shortint]];
}
return array;
}
+ (uint32_t)longintFromArray:(NSArray *)array {
uint8_t shortint, itemIndex = 0;
uint32_t longint = 0;
NSNumber *item;
for (uint8_t i = 0; i < 32; i = i + 4) {
if ([[array objectAtIndex:itemIndex] isKindOfClass:[NSNumber class]]) {
item = [array objectAtIndex:itemIndex];
shortint = [item unsignedShortValue] & 15; // 15 is 00001111 in binary
longint = longint | shortint << i;
}
itemIndex++;
}
return longint;
}

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

if statement comparring keep saying 4 is bigger than 5

I have an array that would has 0-49. When I compare acc_x[i] > acc_x[i-1], it would work for some value until it is comparing 5 and 4, then it say that 4 is bigger than 5 and go into the else statement. Please help.
int main(int argc, const char * argv[])
{
#autoreleasepool {
// insert code here...
//NSLog(#"Hello, World!");
//use velocity not acceleration. sorry for the naming. so run the velocity function for the array first that I wrote a already
NSMutableArray * acc_x = [NSMutableArray array];
NSNumber * temp = 0;
//the highest point or lowest point
NSNumber *highest =0;
NSNumber *lowest = 0;
int flag = 0;
//array for the highest and lowest point
NSMutableArray * array_lowest = [NSMutableArray array];
NSMutableArray * array_highest = [NSMutableArray array];
//array for the time when the highest and the lowest point
NSMutableArray * time_lowest = [NSMutableArray array];
NSMutableArray * time_highest = [NSMutableArray array];
double temp1 = 0;
NSNumber *temp2 = 0;
// the time variable is is just for temp variable. the real variable will be how long it take to have one measurement. i think it was like .001 or something like that but i don't remember. the time have to be in second if it is not in second the conver it.
double time = 0.1;
//trying to find the highest point or the lowest points in the graph from the acceleration
for (int i=0; i<50; i++)
{
//putting 0-49 into the array for testing
temp = [NSDecimalNumber numberWithDouble:i];
[acc_x addObject:temp];
if(i == 2) {
if (acc_x[i] > acc_x[i-1]) {
flag = 0;
}
if(acc_x[i] < acc_x[i-1]){
flag = 1;
}
NSLog(#"flag = %d",flag);
}
if(i>1) {
if(acc_x[i] > acc_x[i-1]) {
NSLog(#"x now is bigger then x past");
}
}
if(i >1) {
if(acc_x[i] > acc_x[i-1]) {
NSLog(#"x now is bigger then x pass");
}
NSLog(#"i = %d , i-1 = %d",i, i-1);
if (flag == 0) {
NSLog(#"flag is 0");
if(acc_x[i] > acc_x[i-1]) {
highest = acc_x[i];
}
else {
NSLog(#"flag going to turn into 1");
[array_highest addObject:highest];
flag = 1;
// calculate the time when the highest point is
temp1 = time * i;
temp2 = [NSNumber numberWithDouble:temp1];
[time_highest addObject:temp2];
}
}
if (flag ==1) {
NSLog(#"flag is 1");
}
}
}
// the size of the array
/* long size = [acc_x count];
for (int i =1; i<size-1; i++) {
NSLog(#"i = %d, flag = %d, array = %#, array[i-1] = %#",i,flag,acc_x[i],acc_x[i-1]);
if (flag == 1) {
if (acc_x[i] < acc_x[i-1]) {
lowest = acc_x[i];
}
if (acc_x[i] > acc_x[i-1]) {
flag = 0;
[array_lowest addObject:lowest];
// the temp1 is storing the time when this point got recorded
temp1 = time * i;
temp2 = [NSNumber numberWithDouble:temp1];
[time_lowest addObject:temp2];
}
}
if (flag == 0) {
if (acc_x[i] > acc_x[i-1]) {
highest = acc_x[i];
NSLog(#"x now is bigger than x-1");
//NSLog("highest = %d", highest);
}
if (acc_x[i] < acc_x[i-1]) {
NSLog(#"x now is less than x-1");
flag = 1;
[array_highest addObject:highest];
// the temp1 is storing the time when this point got recorded
temp1 = time * i;
temp2 = [NSNumber numberWithDouble:temp1];
[time_highest addObject:temp2];
}
}
}*/
//finding the period: time for 1 oscillation in second (remember that it is in second VERY IMPORTANT)
}
return 0;
}
You are comparing objects (NSNumber) instead of their numerical value.
do: if ([acc_x[i] intValue] > [acc_x[i-1] intValue])
instead of if (acc_x[i] > acc_x[i-1])

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.

Cocoa Touch - Comparing Ints

I have a maybe simple problem. I am going to generate 3 random numbers ranging from 0 to 2 and I want to determine if there are any duplicates.
Any ideas?
if (num1 == num2) {
}
else if (num1 == num3) {
}
else if (num2 == num3) {
}
else {
//There are no dups.
}
Checks if there is a duplicate.
if (num1 == num2) {
counter++;
}
if (num1 == num3) {
counter++;
}
if (num2 == num3) {
counter++;
}
This finds how many duplicates there are (for an added bonus).
EDIT:
For x amount of numbers you might want to do this (using 10 as my example amount of ints):
int counter = 0;
int i[10] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
for (int g = 0; g < 10; g++)
{
for (int j = g+1; j < 10; j++)
{
if(i[g] == i[j])
{
counter++;
printf(#"%d\n", counter);
//If this if statement is true then there is a dup... In this case none are found.
}
}
}
How about this?
NSArray *randomNumbers = [[NSArray alloc] initWithObjects:#"0",#"1",#"1",#"2",nil];
NSMutableDictionary *occurenceDict = [[NSMutableDictionary alloc] init];
for (NSString *number in randomNumbers)
{
if ([occurenceDict objectForKey:number] == nil) {
[occurenceDict setValue:[NSNumber numberWithInt:[number intValue]] forKey:number];
int occOfNum = 0;
for (int i = 0; i < [randomNumbers count]; i++) {
NSString *currentNumber = [randomNumbers objectAtIndex:i];
if ([currentNumber compare:number] == NSOrderedSame) {
occOfNum++;
}
}
[occurenceDict setValue:[NSNumber numberWithInt:occOfNum] forKey:number];
}
}
for (NSString *key in occurenceDict) {
NSString *occurrences = [occurenceDict objectForKey:key];
NSLog(#"Number %d is contained %d times", [key intValue], [occurrences intValue]);
}
[randomNumbers release];
[occurenceDict release];
Output:
Number 0 is contained 1 times
Number 1 is contained 2 times
Number 2 is contained 1 times
Edit: Incase you want to know how this works, here is the same version but with comments to help you understand it:
// Create array with the numbers that we have randomly generated
NSArray *randomNumbers = [[NSArray alloc] initWithObjects:#"0",#"1",#"1",#"2",nil];
NSMutableDictionary *occurenceDict = [[NSMutableDictionary alloc] init];
for (NSString *number in randomNumbers)
{
// If this number has not been added to the dictionary
if ([occurenceDict objectForKey:number] == nil) {
// Add it
[occurenceDict setValue:[NSNumber numberWithInt:[number intValue]] forKey:number];
// Find how many times the number occurs with the "randomNumbers" array
int occOfNum = 0;
for (int i = 0; i < [randomNumbers count]; i++) {
NSString *currentNumber = [randomNumbers objectAtIndex:i];
if ([currentNumber compare:number] == NSOrderedSame) {
// We found this number at this index, so increment the found count
occOfNum++;
}
}
// Save the number of times which "number" occurs in the dictionary for later
[occurenceDict setValue:[NSNumber numberWithInt:occOfNum] forKey:number];
}
}
// Iterate through all items in the dictionary and print out the result
for (NSString *key in occurenceDict) {
NSString *occurrences = [occurenceDict objectForKey:key];
NSLog(#"Number %d is contained %d", [key intValue], [occurrences intValue]);
}
// Release alloc'ed memory
[randomNumbers release];
[occurenceDict release];
Crikey, these answers are long-winded! Put your random generated numbers into an NSIndexSet. Test the set before inserting a number and you'll know that the number is already present, and so is a dupe.