Objective C: Array with size repopulate - ios

I need an array where I can store 3 values, and calculate the average of it.
After 3s the array is full, I would like to refresh every value starting from begin [0] of the array. So every 3s the the array is updated and I have the most recent average. For the moment when I add an object the array keeps growing.
This is the code I have at the moment:
//Inside function which loops every second so I can access myValue
self.myArray = [[NSMutableArray alloc] initWithCapacity:3];
[self.myArray addObject:[NSNumber numberWithDouble:myValue]];
for(int i = 0; i < self.myArray.count; i++) {
NSLog(#"Array %d: %#", i, self.myArray[i]);
}
Output
Array 0: 2
Array 1: 4
Array 2: 5
Array 3: 6
Array 4: 1

Just check if the size of your array is larger than 3. If so, remove the oldest element.
Here is a possible implementation:
Alloc and init the array:
self.myArray = [[NSMutableArray alloc] init];
Insert a new object and delete the oldest one:
[self.myArray insertObject:object atIndex:0];
if ( self.myArray.count > 3 )
{
[self.myArray removeLastObject];
}

It looks like you're trying to calculate a running average that gets updated every second. Here's a simple alternative approach that may work for you.
Initialize the average:
runningAverage = myValue;
Inside the loop:
const int WEIGHT = 3;
runningAverage = (runningAverage * (WEIGHT - 1) + myValue) / WEIGHT;
Here's what the output would look like:
Input: 1, 2, 3, 4, 101, 6, 7, 8
(Using an array)
Output: -, -, 2, 3, 36, 37, 38, 7
(Using running average)
Output: 1, 1.33, 1.88, 2.59, 35.4, 25.6, 19.4, 15.6

Related

Missing numbers in nsarray

Good day, For example: If I have an nsarray [3, 1, -5, 3, 3, -5, 0, 1, 1, 3]
How do I calculate Missing numbers in my Array:
-4
-3
-2
-1
2
But - No sorting is allowed and must run in linear time O(N)
Well the brute force way would be something like this
a. find the max and min values in the array -5, 3
b. loop multiple times the array form -5 to 3 looking for the specific number (-5, -4, -3, -2, -1, 0 .... 3)
b1. if the number if found break that loop and continue with the next
b2 . if the loop ends without breaking take note of that number
It's inefficient compared to just sorting it, but it runs in a linear way
The idea is to make another array of bools and to check true if that number exist. After you do that, just go through array of bools and if number is false then its missing.
plz use this code
NSArray *a = #[#3, #1, #-5, #3, #3, #-5, #0, #1, #1, #3];
NSNumber *max=[a valueForKeyPath:#"#max.self"];
NSNumber *min=[a valueForKeyPath:#"#min.self"];
int big = [max intValue];
int small = [min intValue];
while (small<=big) {
if ([a containsObject:[NSNumber numberWithInt:small]]) {
}
else
{
NSLog(#"missing number is %d",small);
}
small++;
}
result
If the numbers in the array are consecutive integers, then 'Sort' the array and find the difference between the two consecutive numbers. If it is 1, then the number is not missed. Else, the number has missed.

True Random Xcode

I'm currently making a quiz app. When a user starts the quiz random questions show up like you would expect from a quiz app. The problem is, it is not quite random. It does show random questions, but the questions repeat. I wanted to make sure they do not repeat until the end! My code is :
int Questions = arc4random_uniform(142);
switch (Questions) {
case 0:
break;
case 1:
break;
(...)
Isn't there a better way to do it? A way to just not repeat the questions? Thank you so much!
A shuffle may be your best solution:
// Setup
int questionCount = 10; // real number of questions
NSMutableArray *questionIndices = [NSMutableArray array];
for (int i = 0; i < questionCount; i++) {
[questionIndices addObject:#(i)];
}
// shuffle
for (int i = questionCount - 1; i > 0; --i) {
[questionIndices exchangeObjectAtIndex: i
withObjectAtIndex: arc4random_uniform((uint32_t)i + 1)];
}
// Simulate asking all questions
for (int i = 0; i < questionCount; i++) {
NSLog(#"questionIndex: %i", [questionIndices[i] intValue]);
}
NSLog output:
questionIndex: 6
questionIndex: 2
questionIndex: 4
questionIndex: 8
questionIndex: 3
questionIndex: 0
questionIndex: 1
questionIndex: 9
questionIndex: 7
questionIndex: 5
ADDENDUM
Example with actual text being printed after shuffling
// Setup
NSMutableArray *question = [NSMutableArray arrayWithObjects:
#"Q0 text", #"Q1 text", #"Q2 text", #"Q3 text", #"Q4 text",
#"Q5 text", #"Q6 text", #"Q7 text", #"Q8 text", #"Q9 text", nil];
// shuffle
for (int i = (int)[question count] - 1; i > 0; --i) {
[question exchangeObjectAtIndex: i
withObjectAtIndex: arc4random_uniform((uint32_t)i + 1)];
}
// Simulate asking all questions
for (int i = 0; i < [question count]; i++) {
printf("%s\n", [question[i] UTF8String]);
}
Sample output:
Q9 text
Q5 text
Q6 text
Q4 text
Q1 text
Q8 text
Q3 text
Q0 text
Q7 text
Q2 text
The idea is to use each question once until all questions have been used.
Sample code. Note that the questionIndex does not repeat.
// Setup
int questionCount = 10; // real number of questions
NSMutableArray *questionIndexes = [NSMutableArray array];
for (int i=0; i<questionCount; i++)
[questionIndexes addObject:#(i)];
// Simulate asking all questions
while (questionIndexes.count) {
// For each round
unsigned long arrayIndex = arc4random_uniform((uint32_t)questionIndexes.count);
int questionIndex = [questionIndexes[arrayIndex] intValue];
[questionIndexes removeObjectAtIndex:arrayIndex];
NSLog(#"arrayIndex: %lu, questionIndex: %i", arrayIndex, questionIndex);
}
NSLog output:
arrayIndex: 9, questionIndex: 9
arrayIndex: 5, questionIndex: 5
arrayIndex: 5, questionIndex: 6
arrayIndex: 3, questionIndex: 3
arrayIndex: 3, questionIndex: 4
arrayIndex: 4, questionIndex: 8
arrayIndex: 2, questionIndex: 2
arrayIndex: 0, questionIndex: 0
arrayIndex: 1, questionIndex: 7
arrayIndex: 0, questionIndex: 1
Any random generator is actually pseudorandom. By default it is started from the same initial value. To make it it "real random" you should supply unique start value i.e. "salt" for each run. As a simplest approach you can use [NSDate timeIntervalSinceReferenceDate].
Put your questions in an array and put the random number in the objectWithIndex method of NSMutableArray. Then remove the question from the array. Whenever a index is chosen, but there is not a question anymore, try it again.

Reverse bit operation in objective-c / c++

I have opposite question for
If i have:
typedef enum {
SUNDAY = (1 << 0),
MONDAY = (1 << 1),
TUESDAY = (1 << 2),
WEDNESDAY = (1 << 3),
THURSDAY = (1 << 4),
FRIDAY = (1 << 5),
SATURDAY = (1 << 6),
} PFDateDays;
And my input is 65 for example (SUNDAY,SATURDAY) there is a clever way for etract this values from enum?
Here is my method:
-(NSMutableArray*)selectFromMyEnum {
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
int myInput = 62;
NSArray *enumArray = #[#(SATURDAY),#(FRIDAY),#(THURSDAY),#(WEDNESDAY),#(TUESDAY),#(MONDAY),#(SUNDAY)];
for(NSNumber *numberInEnumArray in enumArray) {
if(myInput >= [numberInEnumArray integerValue]) {
[returnArray addObject:numberInEnumArray];
myInput -= [numberInEnumArray integerValue];
}
}
NSLog(#"%#",returnArray);
return returnArray;
}
And this is output:
(
64, //SATURDAY
1 //SUNDAY
)
So this is correct. But maybe there is method I don't know about that allow me to do this without this pointless assign enum to array etc..
Well the first thing that comes to my mind is this. Since your enum is nicely laid out for flagging you can do something like this:
Start with your highest enum value (SATURDAY) and use a bitwise and (&) to check if your value contains it. Then shift the comparison value right by 1 and repeat until your comparison value is zero.
PFDateDays comparison = SATURDAY;
//If your enum doesn't end at 1 like the above example,
//you could also use >= SUNDAY
while(((int)comparison) > 0) {
if((myVal & comparison) == comparison)
//Do what you want, this value is valid
comparison = comparison >> 1;
}

Find successive maximum differences in array

I have created an application in which the user continually rotates the phone about the z-axis (yaw) with the screen of the phone facing upwards. I would like to generate the angle between the two extremes each time the rotation changes direction.
Imagine an array of the following values: [-5,-3,-2, 0, 1, 2, 6, 5, 3, 2,-1,-3,-4,-7,-4,-3,...]. What I would like to do is find the relative maximums and minimums of the array in order to find the differences from one relative minimum to the next relative maximum. In the given array, -5 would be the first relative minimum and then 6 would be the next relative maximum. The difference here would be 11 units. From that relative maximum of 6, the next relative minimum is -7. The difference here would be 13 units. The process would continue on until the end of the array. I would like these difference values to be entered into an array of their own, i.e. [11,13,...]. Would greatly appreciate any assistance!
The way I see this your first value in the array is always your initial relative minimum AND maximum since you have absolutely no basis of comparison from the get-go (unless you prime both relMin and relMax to 0 OR define a range to find your relMin and relMax). With that in mind the logic behind your example itself is flawed given your assumption of using -5 & 6 as the first comparison pair.
Let's use your array and iterate through the array with a For Loop...
[-5,-3,-2, 0, 1, 2, 6, 5, 3, 2,-1,-3,-4,-7,-4,-3,...]
0: relMin = -5, relMax = -5, delta = 0
1: relMin = -5, relMax = -3, delta = 2
2: relMin = -5, relMax = -2, delta = 3
3: relMin = -5, relMax = 0, delta = 5
4: relMin = -5, relMax = 1, delta = 6
5: relMin = -5, relMax = 2, delta = 2
6: relMin = -5, relMax = 6, delta = 11
7:
....
13: relMin = -7, relMax = 6, delta = 13
....
Essentially what you're doing is writing to your output array any time your current delta is not equal to your previous delta. Since a change between relMin and relMax is mutually exclusive (only one of those values can change as you traverse the array) all you have to check for is inequality...
//prime your values
//if it make sense for your purposes prime them both with 0
//this also assumes you have at least 1 value in valueArray
relMin = valueArray[0];
relMax = valueArray[0];
//the following line will always be true if you use valueArray[0] as your relMin and relMax baseline
deltaArray[0] = 0;
for (i = 0; i < [valueArray count]; i++)
{
if (valueArray[i] < relMin)
{
relMin = valueArray[i];
}
if (valueArray[i] > relMax)
{
relMax = valueArray[i];
}
deltaPrevious = deltaArray[[deltaArray count] - 1];
deltaCurrent = relMax - relMin;
if (deltaCurrent != deltaPrevious)
{
deltaArray[deltaArray count] = deltaCurrent;
}
}
My approach to this problem would be to first write an algorithm that detects the indices of the maximums and minimums, and then finds differences from there.
To get the maxes and mins, I would recommend iterating through the array and looking at the difference between the current and the previous and next value. You need to looking at changes in sign of the differences:
A minimum will occur when the differences change from negative to positive, and a maximum will occur when the differences change from positive to negative.
For example, look at this part of your array: [1,2,6,5,3]. The difference from 1 to 2 is positive, from 2 to 6 is positive, but from 6 to 5 is negative. The sign of the differences changed from positive to negative at the 6, so we know it is a maximum.
Note that you also need to include the first and last elements as possible maxes or mins.
Once you get the indices of maximums and minimums, you should be able to get their differences fairly easily.
In a most basic sense, you could iterate through the array, checking to see if the next value is greater than or less than the previous value. Whenever you reach a change (was increasing, now decreasing, or vice versa) you have found a relative max/min (respectively). A for loop to iterate, a boolean flag to check against (whether you were increasing or decreasing) and the obvious knowledge of both your current and previous index in the array to check/store.
I don't quite feel comfortable giving exact code for this since it's very basic and seems very much like a homework question...

Enumerate NSArray starting at givven index searching both ways (wrap around)

Example. I've got an array with 15 objects. I want to start enumerating from a given index. Say start at index 5 and then the index above, the index under, above, under etc... I do want it to wrap around.
So the order of indexes in my example would be. 5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0, 11, 14, 12, 13
It would be great to have a method signature similar to following line, but I don't require that to approva an answer:
- (void)enumerateFromIndex:(NSUInteger)index wrapAroundAndGoBothWays:(void (^)(id obj, NSUInteger idx, BOOL *stop))block
How can this be done? Would like to avoid copying array etc.
At this post we do it with no wrap around: Enumerate NSArray starting at givven index searching both ways (no wrap around)
Borrowing from #omz, here is the wrapping variant, which is even simpler:
#implementation NSArray (Extensions)
- (void)enumerateFromIndex:(NSUInteger)index wrapAroundAndGoBothWays:(void (^)(id obj, NSUInteger idx, BOOL *stop))block
{
BOOL stop = NO;
NSUInteger actual = index;
for (NSUInteger i = 0; i < self.count && !stop; i++) {
actual += (2*(i%2)-1)*i;
actual = (self.count + actual)%self.count;
block([self objectAtIndex:actual], actual, &stop);
}
}
#end
This is a mathematical problem. There is a nice solution. However, it involves sorting the list of indexes in advance.
The idea is to lay the integers from 0 to 15 out on a circle and taking the elements in the order they appear on an axis.
Since doing this in ObjC is so tedious, I present the python solution:
from math import pi, cos
def circlesort(N, start):
eps = 1e-8
res = range(N)
def f(x):
return -cos(2*pi*(x-start-eps)/N)
res.sort( lambda x,y:cmp(f(x), f(y)) )
return res
then
print circlesort(15, 5)
outputs
[5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0, 11, 14, 12, 13]
which is the desired result.
EDIT
Okay, here is a C implementation:
#include <stdlib.h>
#include <math.h>
#define sign(x) ((x)>0?1:(x)<0?-1:0)
void circlesort(int* values, int N, int start){
double f(int x)
{
return -cos(2*M_PI*((double)(x-start)-.25)/N);
}
int compare (const void * a, const void * b)
{
return sign( f(*(int*)a) - f(*(int*)b) );
}
qsort (values, N, sizeof(int), compare);
}
This will circlesort an array of integers of lenght N. Use it like this:
int i, N = 15;
int indexes[N];
for (i=0;i<N;i++)
indexes[i] = i;
circlesort(indexes, N, 5);
Now the array indexes is sorted in the desired order. Because there are nested functions, you should add -fnested-functions to the compiler flags.
EDIT 2
Considering the fact that there is a much simpler solution (see my other answer) this one is rather academic.

Resources