How to optimize: add/subtract a value until it is within a predefined range? - objective-c

I have a value range, say the iPhone screen size 480x320. I have a position that may be outside the range, let's say the position's x coordinate is 600 for example.
In order to adjust the x coordinate to its on-screen position I can do: 600 - 480 = 120
But when the value is greater than two times 480 I'd have to run a loop, subtract 480 until the resulting number is below 480.
I know there's an optimization to this problem revolving around division/modulo but I just can't find a good answer (or question) related to this. Mainly because I can only guess possibly helpful search phrases.
I'm feeling sick today and for the live of me I can't wrap my head around it. I'd welcome any pointers, even a "close as duplicate".
PS: this is for Objective-C but any language will do.

You are looking for the modulo operator. The solution for the case of a width of 480 is:
x % 480
Modulo will guarantee that the resulting value is between 0 and 479.

Related

How to place half-block slabs in Minecraft with MakeCode

This is a bit of a long-shot. I really don't know where to ask this question.
I've been trying out CodeConnection + MakeCode with Minecraft and I haven't been able to figure out if there is correct way to place half-slabs at 0.5 step y axes increments.
I tried using a line between 2 points, but it left gaps between each slab.
If I try moving up 0.5, then it rounds it up to 1, and again leaves gaps.
It appears that all of the builder functions seem operate at a resolution of 1 block. However in-game I can obviously place slabs in 0.5 block increments to make stairs etc.
Blocks only exist at integer coordinates. Half slabs that exist in the top half of their space are still at a full integer coordinate. They just have a BlockState value of bottom=top (or top_slot_bit=true on Bedrock, represented by the integer value 8 as a bitflag, eg: 0b1... where the . bits are the integer representation of what type of slab (wood, stone, quartz...)).
What you're looking for is this widget, under Blocks:
You can set the block and then an integer representation of the desired data value (see the wiki on data values) in the numerical slot. This widget can then be dragged into the (block) portion of any block widget:
You'll probably have to some variable fiddling to get the data value to swap back and forth as you need it to, but that should solve the hurdle you've been facing.

1 billionth ugly or hamming number?

Is this the 1 billionth ugly/hamming number?
62565096724471903888424537973014890491686968126921250076541212862080934425144389
76692222667734743108165348546009548371249535465997230641841310549077830079108427
08520497989078343041081429889246063472775181069303596625038985214292236784430583
66046734494015674435358781857279355148950650629382822451696203426871312216858487
7816068576714140173718
Does anyone have code to share that can verify this? Thanks!
This SO answer shows a code capable of calculating it.
The test entry on ideone.com takes 1.1 0.05 sec for 109 (2016-08-18: main speedup due to usage of Int instead of the default Integer where possible, even on 32-bit; additional 20% thanks to the tweak suggested by #GordonBGood, bringing band size complexity down to O(n1/3)).
It gives the answer as ((1334,335,404),"6.21607575556559E+843"), i.e.
21334 * 3335 * 5404 ≈ 6.21607575556559 * 10843.
(coincidentally, only two last digits in the fractional number above are incorrect).
This also means, of course, that there are 404 zeroes at the end of this number, and that it has 844 digits in total. So no, the number you show isn't it.
Exact answer:
6216075755565244861630816332872072003947056519089652706591632409642337022002753141824417540777256732780370172616615291935540418620025524916729500086831454711313694078635504004160312872951788703647948382456091072701600790562071797590306654765882256990391763887850141154482249915927439184562828227449023750262318234797192076792208033475638322151983772515798004125909334741121595323950448656375104457026997424772966917441779406172736975588556800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Understanding Google Code Jam 2013 - X Marks the Spot

I was trying to solve Google Code Jam problems and there is one of them that I don't understand. Here is the question (World Finals 2013 - problem C): https://code.google.com/codejam/contest/2437491/dashboard#s=p2&a=2
And here follows the problem analysis: https://code.google.com/codejam/contest/2437491/dashboard#s=a&a=2
I don't understand why we can use binary search. In order to use binary search the elements have to be sorted. In order words: for a given element e, we can't have any element less than e at its right side. But that is not the case in this problem. Let me give you an example:
Suppose we do what the analysis tells us to do: we start with a left bound angle of 90° and a right bound angle of 0°. Our first search will be at angle of 45°. Suppose we find that, for this angle, X < N. In this case, the analysis tells us to make our left bound 45°. At this point, we can have discarded a viable solution (at, let's say, 75°) and at the same time there can be no more solutions between 0° and 45°, leading us to say that there's no solution (wrongly).
I don't think Google's solution is wrong =P. But I can't figure out why we can use a binary search in this case. Anyone knows?
I don't understand why we can use binary search. In order to use
binary search the elements have to be sorted. In order words: for a
given element e, we can't have any element less than e at its right
side. But that is not the case in this problem.
A binary search works in this case because:
the values vary by at most 1
we only need to find one solution, not all of them
the first and last value straddle the desired value (X .. N .. 2N-X)
I don't quite follow your counter-example, but here's an example of a binary search on a sequence with the above constraints. Looking for 3:
1 2 1 1 2 3 2 3 4 5 4 4 3 3 4 5 4 4
[ ]
[ ]
[ ]
[ ]
*
I have read the problem and in the meantime thought about the solution. When I read the solution I have seen that they have mostly done the same as I would have, however, I did not thought about some minor optimizations they were using, as I was still digesting the task.
Solution:
Step1: They choose a median so that each of the line splits the set into half, therefore there will be two provinces having x mines, while the other two provinces will have N - x mines, respectively, because the two lines each split the set into half and
2 * x + 2 * (2 * N - x) = 2 * x + 4 * N - 2 * x = 4 * N.
If x = N, then we were lucky and accidentally found a solution.
Step2: They are taking advantage of the "fact" that no three lines are collinear. I believe they are wrong, as the task did not tell us this is the case and they have taken advantage of this "fact", because they assumed that the task is solvable, however, in the task they were clearly asking us to tell them if the task is impossible with the current input. I believe this part is smelly. However, the task is not necessarily solvable, not to mention the fact that there might be a solution even for the case when three mines are collinear.
Thus, somewhere in between X had to be exactly equal to N!
Not true either, as they have stated in the task that
You should output IMPOSSIBLE instead if there is no good placement of
borders.
Step 3: They are still using the "fact" described as un-true in the previous step.
So let us close the book and think ourselves. Their solution is not bad, but they assume something which is not necessarily true. I believe them that all their inputs contained mines corresponding to their assumption, but this is not necessarily the case, as the task did not clearly state this and I can easily create a solvable input having three collinear mines.
Their idea for median choice is correct, so we must follow this procedure, the problem gets more complicated if we do not do this step. Now, we could search for a solution by modifying the angle until we find a solution or reach the border of the period (this was my idea initially). However, we know which provinces have too much mines and which provinces do not have enough mines. Also, we know that the period is pi/2 or, in other terms 90 degrees, because if we move alpha by pi/2 into either positive (counter-clockwise) or negative (clockwise) direction, then we have the same problem, but each child gets a different province, which is irrelevant from our point of view, they will still be rivals, I guess, but this does not concern us.
Now, we try and see what happens if we rotate the lines by pi/4. We will see that some mines might have changed borders. We have either not reached a solution yet, or have gone too far and poor provinces became rich and rich provinces became poor. In either case we know in which half the solution should be, so we rotate back/forward by pi/8. Then, with the same logic, by pi/16, until we have found a solution or there is no solution.
Back to the question, we cannot arrive into the situation described by you, because if there was a valid solution at 75 degrees, then we would see that we have not rotated the lines enough by rotating only 45 degrees, because then based on the number of mines which have changed borders we would be able to determine the right angle-interval. Remember, that we have two rich provinces and two poor provinces. Each rich provinces have two poor bordering provinces and vice-versa. So, the poor provinces should gain mines and the rich provinces should lose mines. If, when rotating by 45 degrees we see that the poor provinces did not get enough mines, then we will choose to rotate more until we see they have gained enough mines. If they have gained too many mines, then we change direction.

Objective C, division between floats not giving an exact answer

Right now I have a line of code like this:
float x = (([self.machine micSensitivity] - 0.0075f) / 0.00025f);
Where [self.machine micSensitivity] is a float containing the value 0.010000
So,
0.01 - 0.0075 = 0.0025
0.0025 / 0.00025 = 10.0
But in this case, it keeps returning 9.999999
I'm assuming there's some kind of rounding error but I can't seem to find a clean way of fixing it. micSensitivity is incremented/decremented by 0.00025 and that formula is meant to return a clean integer value for the user to reference so I'd rather get the programming right than just adding 0.000000000001.
Thanks.
that formula is meant to return a clean integer value for the user to reference
If that is really important to you, then why do you not multiply all the numbers in this story by 10000, coerce to int, and do integer arithmetic?
Or, if you know that the answer is arbitrarily close to an integer, round to that integer and present it.
Floating-point arithmetic is binary, not decimal. It will almost always give rounding errors. You need to take that into account. "float" has about six digit precision. "double" has about 15 digits precision. You throw away nine digits precision for no reason.
Now think: What do you want to display? What do you want to display if the result of your calculation is 9.999999999? What would you want to display if the result is 9.538105712?
None of the numbers in your question, except 10.0, can be exactly represented in a float or a double on iOS. If you want to do float math with those numbers, you will have rounding errors.
You can round your result to the nearest integer easily enough:
float x = rintf((self.machine.micSensitivity - 0.0075f) / 0.00025f);
Or you can just multiply all your numbers, including the allowed values of micSensitivity, by 4000 (which is 1/0.00025), and thus work entirely with integers.
Or you can change the allowed values of micSensitivity so that its increment is a fraction whose denominator is a power of 2. For example, if you use an increment of 0.000244140625 (which is 2-12), and change 0.0075 to 0.00732421875 (which is 30 * 2-12), you should get exact results, as long as your micSensitivity is within the range ±4096 (since 4096 is 212 and a float has 24 bits of significand).
The code you have posted is correct and functioning properly. This is a known side effect of using floating point arithmetic. See the wiki on floating point accuracy problems for a dull explanation as to why.
There are several ways to work around the problem depending on what you need to use the number for.
If you need to compare two floats, then most everything works OK: less than and greater than do what you would expect. The only trouble is testing if two floats are equal.
// If x and y are within a very small number from each other then they are equal.
if (fabs(x - y) < verySmallNumber) { // verySmallNumber is usually called epsilon.
// x and y are equal (or at least close enough)
}
If you want to print a float, then you can specify a precision to round to.
// Get a string of the x rounded to five digits of precision.
NSString *xAsAString = [NSString stringWithFormat:#"%.5f", x];
9.999999 is equal 10. there is prove:
9.999999 = x then 10x = 99.999999 then 10x-x = 9x = 90 then x = 10

Value of NSUInteger and NaN?

Why is the value of NSUInteger 2^32 - 1 instead of 2^32? Is there a relationship between this fact and the need of a nan value? This is so confusing.
Count to 10 on your fingers. Really :)
The standard way to count to 10 is 1,2,3,..10 (the ordinality of each finger is counted). However, what about "0 fingers"?
Normally that might represent that by putting your hands behind our back, but that adds another piece of information to the system: are your hands in front (present) or behind (missing)?
In this case, putting hands behind your back would equivalent to assigning nil to an NSNumber variable. However, NSUInteger represents a native integer type which does not have this extra state and must still encode 0 to be useful.
The key to encode the value 0 on your fingers is to simply count 0,1,2..9 instead. The same number of fingers (or bits of information) are available, but now the useful 0 can be accounted for .. at the expense of not having a 10 value (there are still 10 fingers, but the 10th finger only represents the value 9). This is the same reason why unsigned integers have a maximum value of 2^n-1 and not 2^n: it allows 0 to be encoded with maximum efficiency.
Now, NaN is not a typical integer value, but rather comes from floating point encodings - think of float or CGFloat. One such common encoding is IEEE 754:
In computing, NaN, standing for not a number, is a numeric data type value representing an undefined or unrepresentable value, especially in floating-point calculations ..
2^32-1 because counting starts from 0 for bits. If it's easier think of it as 2^32 - 2^0.
It is the largest value a 32-bit unsigned integer variable can hold. Add one to that, and it will wrap around to zero.
The reason for that is that the smallest unsigned number is zero, not one. Think of it: the largest number you can fit into four decimal places is 9999, not 10000. That's 10^4-1.
You cannot store 2^32 in 4 bytes, but if you subtract one then it fits (result is 0xffffffff)
Exactly the same reason why the odometer in your car shows a maximum of 999999 mi/km (assuming 6 digits) - while there are 10^6 possible values it can't show 10^6 itself but 0 through 10^6-1.