How to save multiple small integers in one integer via bit shifting in Objective C - 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;
}

Related

Find adjacent boxes to a box in a 4x4 grid

I've an array with 1 to 16 numbers self.gridArray = [[NSMutableArray alloc]initWithObjects:#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"11",#"12",#"13",#"14",#"15",#"16", nil];
I am using this function to randomize or shuffle the array items
-(void)randomizeArray:(NSMutableArray *)myArray{
NSUInteger count = [myArray count];
for (NSUInteger i = 0; i < count; ++i)
{
unsigned long int nElements = count - i;
unsigned long int n = (arc4random() % nElements) + i;
[myArray exchangeObjectAtIndex:i withObjectAtIndex:n];
}
NSLog(#"%#",myArray);
}
This function is working perfectly. My question is that suppose it gives me the shuffled array as (9,15,3,5,1,6,7,8,14,13,12,2,16,10,4,11) which I have placed it in a 4x4 grid. Now I want to find the adjacent numbers for lets say 7 they will be 6,3,8,12. How to find them? Another example if I want to find adjacent numbers of 11 they will be 2,4.
Try this:
NSInteger idx = (NSInteger)[myArray indexOfObject:#"11"]; //obtain the index of the target number
NSMutableArray *adjacentNumbers = [[NSMutableArray alloc] init];
if ( idx+4 < 16 ) { [adjacentNumbers addObject:[myArray objectAtIndex:(NSUInteger)(idx+4)]]; } //number below
if ( idx+1 < 16 && (idx%4 != 3) ) { [adjacentNumbers addObject:[myArray objectAtIndex:(NSUInteger)(idx+1)]]; } //number on the right
if ( idx-4 >= 0 ) { [adjacentNumbers addObject:[myArray objectAtIndex:(NSUInteger)(idx-4)]]; } //number above
if ( idx-1 >= 0 && (idx%4 != 0) ) { [adjacentNumbers addObject:[myArray objectAtIndex:(NSUInteger)(idx-1)]]; } //number on the left

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

Why does my sorted array occasionally return random 0s at the end?

I wrote a program to sort a randomly generated array of 50 integers from greatest to least. So far it works, but it will occasionally return random zeros at the end of the sorted array. These zeros are not present in the unsorted array, and they do not always appear. Here's my program:
#import <Foundation/Foundation.h>
#interface Number: NSObject
- (void) start;
- (int) getValue;
- (void) counted;
- (void) placeValue: (int) a;
#end
#implementation Number
{
int x;
}
- (void) start
{
x = arc4random_uniform(1000);
if (x == 1)
{
x = x+1;
}
}
- (int) getValue
{
return x;
}
- (void) counted
{
x = 0;
}
- (void) placeValue: (int) a
{
x = a;
}
#end
int main(int argc, const char * argv[])
{
#autoreleasepool
{
NSMutableArray *unsortedArray = [[NSMutableArray alloc] initWithCapacity: 50];
for (int n = 0; n < 50; n++)
{
Number *num = [[Number alloc] init];
[num start];
[unsortedArray addObject: num];
}
for (int n = 0; n < 50; n++)
{
printf("%i, ", [unsortedArray[n] getValue]);
}
printf ("unsorted array.\n\n");
int x = 0;
int y = 1001;
for (int n = 0; n < 50; n++)
{
for (int m = 0; m < 50; m++)
{
if (([unsortedArray[m] getValue] > x) && ([unsortedArray[m] getValue] < y))
{
x = [unsortedArray[m] getValue];
}
}
printf("%i, ", x);
y = x;
x = 0;
}
printf("sorted array.\n");
} return 0;
}
Try this:
- (void)start
{
x = (arc4random_uniform(1000) + 1);
}
You don't want to only be increasing x when you hit 0 or 1, since that will skew the results. arc4random_uniform will return a random number less than 1000 in this case, so 0 -> 999, adding 1 to all values, gives you 1 -> 1000. Adjust your numbers to suit what you need.
There are other issues in your code though. Why create your own Number class? Why create your own sort method? Use NSNumber and NSArray's sort methods.
Here is a much cleaner version:
int main(int argc, const char * argv[])
{
#autoreleasepool
{
NSMutableArray* unsortedArray = [[NSMutableArray alloc] initWithCapacity:50];
for (NSUInteger n = 0; n < 50; ++n) {
[unsortedArray addObject:#(arc4random_uniform(999) + 1)];
}
for (NSUInteger n = 0; n < 50; ++n) {
printf("%li, ", (long)[unsortedArray[n] integerValue]);
}
printf ("unsorted array.\n\n");
NSArray* sortedArray = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj2 compare:obj1];
}];
for (NSUInteger n = 0; n < 50; ++n) {
printf("%li, ", (long)[sortedArray[n] integerValue]);
}
printf("sorted array.\n");
}
return 0;
}
- (void) start
{
x = arc4random_uniform(1000);
if (x == 0)
x = x + 1;
}
Everyone is focusing on the fact that arc4random_uniform can generate zero as an acceptable value (which is true), but there is another problem: Your sort algorithm is incorrect, as it will only work if the values in the array are unique. But, if you have any duplicate values (and there's no assurances that arc4random_uniform won't generate some duplicates), your algorithm will show only one of those values, and thus, by the time you get to the end, you'll see a bunch of extra zeros.
There are tons of different sorting algorithms, but it's probably easier to just avail yourself of one of the native NSMutableArray sort methods, which gets you out of the weeds of writing your own.

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

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.

Randomly select x amount of items in a "list"

I would like to select x amount of items randomly from a "list" in objective C store them in an other "list" (each item can only be selected one) , I'm talking about lists because I'm coming from Python. What would be the best way to store a list of strings in Objective C ?
cheers,
You should use NSMutableArray class for changeable arrays or NSArray for non-changeable ones.
UPDATE: a piece of code for selecting a number of items from an array randomly:
NSMutableArray *sourceArray = [NSMutableArray array];
NSMutableArray *newArray = [NSMutableArray array];
int sourceCount = 10;
//fill sourceArray with some elements
for(int i = 0; i < sourceCount; i++) {
[sourceArray addObject:[NSString stringWithFormat:#"Element %d", i+1]];
}
//and the magic begins here :)
int newArrayCount = 5;
NSMutableIndexSet *randomIndexes = [NSMutableIndexSet indexSet]; //to trace new random indexes
for (int i = 0; i < newArrayCount; i++) {
int newRandomIndex = arc4random() % sourceCount;
int j = 0; //use j in order to not rich infinite cycle
//tracing that all new indeces are unique
while ([randomIndexes containsIndex:newRandomIndex] || j >= newArrayCount) {
newRandomIndex = arc4random() % sourceCount;
j++;
}
if (j >= newArrayCount) {
break;
}
[randomIndexes addIndex:newRandomIndex];
[newArray addObject:[sourceArray objectAtIndex:newRandomIndex]];
}
NSLog(#"OLD: %#", sourceArray);
NSLog(#"NEW: %#", newArray);