finding the closest Int value from a set of int values in objective c - objective-c

objective c math function question
I've got a x value that i'd like to compare to other values within a set, then determine which value from the set my x value is closest to.
For example, lets say i've got the ints 5, 10, 15, 20, 25.
What is the best way to determine which of these numbers is closest to 7?

int closestDistance = INT32_MAX;
int indexOfClosestDistance = -1;
int x = 7;
for (int i=0; i < [yourArray count]; i++)
{
int num = yourArray[i];
int diff = abs(num - x);
if (diff < closestDistance)
{
closestDistance = diff;
indexOfClosestDistance = i ;
}
}
Best of luck

Neither Objective-C nor Cocoa provides anything that solves this for you. You can store your ints in a plain old array of int, or you can wrap each one in an NSNumber and store the wrappers in an NSArray.
If you're going to probe the array many times, sort it once in advance, and then for each probe use a binary search (standard C function bsearch or Core Foundation's CFArrayBSearchValues or Cocoa's -[NSArray indexOfObject:inSortedRange:options:usingComparator:]) to find the nearest two elements. If you're only going to probe the array once or twice, just use a for loop, subtraction, abs, and MIN.

The easiest way is subtract the smaller number from the larger one. So you'd want to compare the two numbers first, then just do simple subtraction. So you'd see the 10-7 is 3 away, and 7-5 is only 2 away.

Related

Get the most occuring number amongst several integers without using arrays

DISCLAIMER: Rather theoretical question here, not looking for a correct answere, just asking for some inspiration!
Consider this:
A function is called repetitively and returns integers based on seeds (the same seed returns the same integer). Your task is to find out which integer is returned most often. Easy enough, right?
But: You are not allowed to use arrays or fields to store return values of said function!
Example:
int mostFrequentNumber = 0;
int occurencesOfMostFrequentNumber = 0;
int iterations = 10000000;
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
int occurencesOfResult = magic();
if(occurencesOfResult > occurencesOfMostFrequentNumber)
{
mostFrequentNumber = result;
occurencesOfMostFrequentNumber = occurencesOfResult;
}
}
If getNumberFromSeed() returns 2,1,5,18,5,6 and 5 then mostFrequentNumber should be 5 and occurencesOfMostFrequentNumber should be 3 because 5 is returned 3 times.
I know this could easily be solved using a two-dimentional list to store results and occurences. But imagine for a minute that you can not use any kind of arrays, lists, dictionaries etc. (Maybe because the system that is running the code has such a limited memory, that you cannot store enough integers at once or because your prehistoric programming language has no concept of collections).
How would you find mostFrequentNumber and occurencesOfMostFrequentNumber? What does magic() do?? (Of cause you do not have to stick to the example code. Any ideas are welcome!)
EDIT: I should add that the integers returned by getNumber() should be calculated using a seed, so the same seed returns the same integer (i.e. int result = getNumber(5); this would always assign the same value to result)
Make an hypothesis: Assume that the distribution of integers is, e.g., Normal.
Start simple. Have two variables
. N the number of elements read so far
. M1 the average of said elements.
Initialize both variables to 0.
Every time you read a new value x update N to be N + 1 and M1 to be M1 + (x - M1)/N.
At the end M1 will equal the average of all values. If the distribution was Normal this value will have a high frequency.
Now improve the above. Add a third variable:
M2 the average of all (x - M1)^2 for all values of xread so far.
Initialize M2 to 0. Now get a small memory of say 10 elements or so. For every new value x that you read update N and M1 as above and M2 as:
M2 := M2 + (x - M1)^2 * (N - 1) / N
At every step M2 is the variance of the distribution and sqrt(M2) its standard deviation.
As you proceed remember the frequencies of only the values read so far whose distances to M1 are less than sqrt(M2). This requires the use of some additional array, however, the array will be very short compared to the high number of iterations you will run. This modification will allow you to guess better the most frequent value instead of simply answering the mean (or average) as above.
UPDATE
Given that this is about insights for inspiration there is plenty of room for considering and adapting the approach I've proposed to any particular situation. Here are some thoughts
When I say assume that the distribution is Normal you should think of it as: Given that the problem has no solution, let's see if there is some qualitative information I can use to decide what kind of distribution would the data have. Given that the algorithm is intended to find the most frequent number, it should be fine to assume that the distribution is not uniform. Let's try with Normal, LogNormal, etc. to see what can be found out (more on this below.)
If the game completely disallows the use of any array, then fine, keep track of only, say 10 numbers. This would allow you to count the occurrences of the 10 best candidates, which will give more confidence to your answer. In doing this choose your candidates around the theoretical most likely value according to the distribution of your hypothesis.
You cannot use arrays but perhaps you can read the sequence of numbers two or three times, not just once. In that case you can read it once to check whether you hypothesis about its distribution is good nor bad. For instance, if you compute not just the variance but the skewness and the kurtosis you will have more elements to check your hypothesis. For instance, if the first reading indicates that there is some bias, you could use a LogNormal distribution instead, etc.
Finally, in addition to providing the approximate answer you would be able to use the information collected during the reading to estimate an interval of confidence around your answer.
Alright, I found a decent solution myself:
int mostFrequentNumber = 0;
int occurencesOfMostFrequentNumber = 0;
int iterations = 10000000;
int maxNumber = -2147483647;
int minNumber = 2147483647;
//Step 1: Find the largest and smallest number that _can_ occur
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
if(result > maxNumber)
{
maxNumber = result;
}
if(result < minNumber)
{
minNumber = result;
}
}
//Step 2: for each possible number between minNumber and maxNumber, count occurences
for(int thisNumber = minNumber; thisNumber <= maxNumber; thisNumber++)
{
int occurenceOfThisNumber = 0;
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
if(result == thisNumber)
{
occurenceOfThisNumber++;
}
}
if(occurenceOfThisNumber > occurencesOfMostFrequentNumber)
{
occurencesOfMostFrequentNumber = occurenceOfThisNumber;
mostFrequentNumber = thisNumber;
}
}
I must admit, this may take a long time, depending on the smallest and largest possible. But it will work without using arrays.

How to combine 2 different integers to create a single float (or a double)

I'm Cesare from Italy (please excuse my english), this is my first question posted on StackOverflow and I'm pretty new to Objective-C... I hope I won't make a mess on my first try.
I would like to "combine" two integers that I already have to create a new float (or a double).
By "combine", I mean that I'd like to have the first int before the point and the second int after the point, I'm not trying to convert from int to float. Maybe an example could explain better what I'm trying to do:
First int: 7
Second int: 92
The float I'm trying to get: 7.92
I looked for a previous question like mine but I haven't found anything, maybe because what I'm trying to do is pretty dumb (I have a UIPickerView with 2 components, each containing hundreds of integers, and I'm trying to create a float or double variable that has the selection of the first component before the point and the selection of the second component after the point).
Thanks in advance for your help,
Cesare
Just think about what the definition and/or the purpose of the decimal point is. It separates the part of the number which is less than one from the part greater than or equal to one.
So, keep dividing the part after the decimal point until it's less than 1:
int firstPart = 7;
int secondPart = 92; // or whatever
float f = secondPart;
while (f >= 1) {
f /= 10;
}
f += firstPart;
I know this is later, but came across a similar situation. Maybe this is more efficient.
Take the second number, 92 and divide it by 100. That gives you .92. Add that to the first number. That can give you 7.92. However, since you're adding integers that you want converted to a float, you'll need to cast the numbers when adding them. Like this:
int firstPart = 7;
int secondPart = 92;
float afterDecimalPlace = (float)secondPart/100.0;
float numberAsFloat = (float)firstPart + afterDecimalPlace;
essentially that is:
92/100 = .92
7 + .92 = 7.92

objective-c check equality of float and int -- does 2.0000 == 2

Simple question, I know there must be a correct way to do this. I have a CGFloat that increases in increments of 1/16. I want to determine when this value becomes a whole number.
For lack of knowing the right way I am coming up with ideas like having another variable to keep track of the number of iterations and mod 16 it.
While you generally can't count on fractional floating point numbers to sum up to whole numbers, your case is exception to the rule since 1/16 is 2^(-4) and this number can be represented by float precisely:
- (void)testFloat
{
float a = 0.0f;
while (a != 2.0f) {
a += 0.0625f;
}
NSLog(#"OK!");
}
It's better to do it the other way around, i.e. use an integer loop counter and convert this to a float:
for (int i = 0; i < 100; ++i)
{
float x = (float)i / 16.0f;
if (i % 16 == 0)
{
// if x is whole number...
}
}
Floating point arithmetic is inexact so you can't count on the value of your variable ever being exactly 2.0000.
"For lack of knowing the right way I am coming up with ideas like having another variable to keep track of the number of iterations andmod 16 it."
This is a wonderful idea.

Algorithm for max and min? (Objective-C)

This is a part of a book I'm reading to learn Objective-C.
The following defines a macro called MAX that gives the maximum of two
values: #define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
And then there are some exercises in the book that asks the reader to define a macro (MIN) to find the minimum of two values and another that asks to define a macro called MAX3 that gives the maximum of 3 values. I think these two definitions will look similar to MAX, but I don't understand how the MAXformula finds the maximum value. I mean if I just did this
int limits = MAX (4,8)
It'll just assign limits the value of 8. What does that have to do with finding a variable's maximum value?
I think you are confusing value and variable. The macro example you listed expands to a comparison between two values and returns the greater of the two values (i.e. which is greater, a or b). So you are right, int limits = MAX(4,8) just assigns 8 to limits and has nothing to do with finding the maximum value you can store in limits.
The header limits.h defines many values like INT_MAX that will tell you information about the min/max values of variable types on your system.
To break it apart:
The declaration:
#define MAX(a,b)
If a is greater than b, use a else use b:
( ((a) > (b)) ? (a) : (b) )
Then to create a MIN expression, use a similar form:
#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
^
Then to create a MAX3 expression, you can combine them:
#define MAX3(a,b,c) ( MAX(a, MAX(b,c)) )
Specifically, this macro's intended to be used with scalars (C builtins) which can be compared using < or >. If you passed an objc variable, it would result in comparison of addresses and MAX would return the one with the higher address (it would be very rare if you actually wanted to compare addresses of objc instances).
Also note that this is the classic example of how macros can bite you. With macros, the preprocessor simply expands (textual copy/paste) the parameters in place, so: int limits = MAX (4,8) literally expands to int limits = (4 > 8 ? 4 : 8). If you write MAX(x,++y), then y will be incremented twice if y is greater than or equal to x because it expands to: int limits = (x > ++y ? x : ++y).
generally, you will use a MAX() or MIN() macro to get whichever is the higher/lower of a pair of variables, or of a variable and a constant, or even a pair of macro constants or other non-literal constant expressions. you generally won't supply 2 literal constants as you have done in your question.
Algorithm for max (Objective-C)
// get max value
- (float)maxValue:(NSArray *)arrValue
{
float maxValue = 0.0;
for (NSString *value in arrValue) {
float compareValue = [value floatValue];
if (compareValue > maxValue) {
maxValue = compareValue;
}
}
return maxValue;
}
NSArray *number=[NSArray arrayWithObjects:[NSNumber numberWithFloat:57.02], [NSNumber numberWithFloat:55.02], [NSNumber numberWithFloat:45.02], nil];
NSLog(#"%f", [self maxValue:number]);
result 57.020000

How to reset C array so all elements are 0

If I have int someArray[100] that contains items in various elements, how can I reset them all back to 0?
Basic question, I know, but I usually use Objective-C arrays however for this purpose I'm just storing some numbers and want to deal with it "old school."
You need to set each element to the value you want:
for (int i = 0; i < 100; ++i)
SomeArray[i] = 0;
For the specific case of integers and the value 0, you can also make use of the fact that their bitwise representation is known (all bits are 0), and so you can use memset:
memset(SomeArray, 0, sizeof(SomeArray));
You can use memset:
memset(someArray, 0, sizeof(someArray));