Shorthand for "If greater than, then equal to" in Acttionscript? - java

Is there a shorthand method to write the following code? Often in games we want to make sure certain things dont leave a boundary, or more generally, we want to stop an index of an array from going beyond the bounds of an array. I've always written it this way, but am wondering if there is a shorthand in Actionscript, Java, or C#
In Actionscript:
index++;
if (index > array.length - 1) index = array.length - 1;
as far as I can tell, there is no operator that accomplishes this, though perhaps I am mistaken. I know the ternary operator is similar if (condition) ? value if true : value if false

You can use Math.min :
index = Math.min (index+1, array.length-1);

For the generic condition of if (condition) set variable (as opposed to your specific case) you could use the following:
variable = (condition) ? (set if true) : (set if false)
In your case, this turns in to:
index = index > array.length - 1 ? index = array.length - 1 : index;
It works in Java, Actionscript, and C#.

If your code looks like this (C#):
index++;
if (index > array.length - 1)
index = array.length - 1;
You're doing the equality testing no matter what anyway, so why not do it before the assignment?
if (index < array.Length)
index++;
I don't know of any shorter method in C#, but you could write your own extension to use, so you don't have to copy/paste the check throughout your code:
public static class ArrayExtensions
{
// Returns the index if it falls within the range of 0 to array.Length -1
// Otherwise, returns a minimum value of 0 or max of array.Length - 1
public static int RangeCheck(this Array array, int index)
{
return Math.Max(Math.Min(index, array.Length - 1), 0);
}
}
To use it:
var index = yourArray.RangeCheck(index);

Try the following, it's also more efficient because you won't make unnecessary increments:
if( index < array.length ) index++;

Related

How to properly handle max/min int value edge case-Java

I am working on a problem from LeetCode (not an interview question just practicing) that asks the following:
Given a sorted integer array nums, where the range of elements are in the inclusive range [lower, upper], return its missing ranges.
The code that I came up with fails for inputs where the nums array is [-2147483648,2147483647] and lower/upper are -2147483648/2147483647 respectively. The part of my code that actually answers the question is:
if (nums[0]-lower > 1) {
String range = lower + "->" + (nums[0]-1);
ans.add(range);
}
else if (nums[0]-lower == 1) {
String range = new Integer(lower).toString();
ans.add(range);
}
for (int i = 1; i < nums.length; i++) {
if (nums[i] - nums[i-1] > 2) {
String range = nums[i-1]+1 + "->" + (nums[i]-1);
ans.add(range);
}
else if (nums[i] - nums[i-1] == 2) {
String range = new Integer(nums[i]-1).toString();
ans.add(range);
}
}
I was wondering how best to handle this edge case, not just for this question but generally. Do I just add extra if-statements to my code to specifically handle these two numbers (or if addition/subtraction of numbers causes the int value to overflow) or is there a more elegant way to handle this?
The maximum value of an int is 231-1 which is 2147483647, but the difference between that number and any negative number is larger than that number itself.
So all your subtraction expressions like nums[0]-lower overflow with [-2147483648,2147483647] (or [-1,2147483647]).
You can check it with this:
System.out.println(2147483647 - -1);
This prints out -2147483648 even though you would expect it to be 2147483648.
One easy fix is to do the calculations as a 64-bit long. Change all your subtractions like below to cast the expression to long.
if (nums[0] - (long)lower > 1) {
Take the above example and change it to:
System.out.println(2147483647 - (long) -1);
This will correctly print 2147483648.

I don't understand the difference

I was reviewing some Java code with this line
if ( list.size() == 1 || list.size() <= 4) {...}
I commented that I do not see how that is any different from just doing
if (list.size() <= 4) {...}
he said it matters and needs to be the first. I don't understand. Perhaps if it were something like
if (list.size() == 1 || list.size() <= someVeryCostlyFunction() ) {...}
and the size was expected to be 1 most of the time you might use both, if someVeryCostlyFunction() always returns some positive number >= 1. Otherwise I can't see the difference. We are supposed to check for efficiency.
The code smells with those two conditions:
if (list.size() == 1 || list.size() <= 4)
Perhaps the author have that in mind:
if there is some number of elements in the list that is 4 or less.
More over the current code allows to satisfy the condition even if the list has zero elements - which is most likely wrong.
Another problem with this condition is use of magic number 4?
What is so important about it and why it is not 5?
It should be self documented and distinguished from other 4's that could appear in the code:
int MAX_HANDLED = 4;
if ( list.size() > 0 && list.size() <= MAX_HANDLED )
:
:
int ALL_TIRES = 4;
if (car.getTires() < ALL_TIRES) {
car.stop();
}
As for the performance, I do not see any significant reason why existing condition should be any faster then yours proposed one (even the second would be faster when list.size > 1). See this question of similar concern.

Rotate Squared Matrix java solution: Why it works?

I want to solve the following problem: You are given an n x n 2D matrix representing an image.
Rotate the image by 90 degrees (clockwise) in-place. I found one very nice solution here: http://n00tc0d3r.blogspot.de/2013/05/rotate-image.html Namely,
public void rotate(int[][] matrix) {
for (int level = 0, len = matrix.length; level < len; ++level, --len) {
int end = len - 1;
for (int pos = level; pos < end; ++pos) {
int tail = matrix.length - pos - 1;
int tmp = matrix[level][pos];
// left -> top
matrix[level][pos] = matrix[tail][level];
// bottom -> left
matrix[tail][level] = matrix[end][tail];
// right -> bottom
matrix[end][tail] = matrix[pos][end];
// top -> right
matrix[pos][end] = tmp;
}
}
}
I see that it works, and I understand the idea, but my question is why we use ++level instead of level++ and why we use --len instead of len--. I tried both was and it worked fine for me. However for such problems (non trivial matrix traversal) people always use ++level instead of level++. Again my question is why?
Consider this :
i = 0;
System.out.println(i++); // postfix increment
This prints 0, but i is updated to 1 as you expect.
i = 0;
System.out.println(++i); // prefix increment
This prints 1.
From Java Langauge Specification,
The value of the postfix increment expression is the value of the variable before the new value is stored.
And
The value of the prefix increment expression is the value of the variable after the new value is stored.
In your case of a for loop, it does not make a difference on which one you use, but it's really a matter of choice and habit.
There is no difference between using ++level or level++ / --len or len-- in an increment/decrement part of the for loop. The len or level values are not used in that section of the loop. so, the values are going to be very same after the execution of that part of the for loop. It is just programmer's decision. That's all
++level is evaluated after the increment and level++ before. The difference is subtle.
As the values of ++level and ++len aren't used in any expressions it's just a matter of style.
It does not have any effect in this "for" loop, but the prefix operator is applied before evaluation of the expression it is used within and the suffix operator after evaluation.
An example where it would make a difference is
while (i++ < 5)
{
foo(bar);
}
or
while (++i < 5)
{
foo(bar);
}
(The former one will go through one additional iteration compared to the latter one since it increments after evaluation of the comparison)

bubble sort string array

I'm trying to use a bubble sort to alphabetize an array that I've read into a program. The code compiles without error but I get an Array Index Out Of Bounds Exception on my 'if' construct when I try to run the program. I have initialized int i to 0 to account for the first index of the array so I think my error is elsewhere. I'm not asking anyone to write code for me, just maybe a point in the right direction. Thanks for any help.
public static String[] bubbleSort(String[] inL)
{
String temp;
int i = 0, passNum;
for(passNum = 1; passNum <= (inL.length); i++) // controls passes through bubble sort
{
if(inL[i].compareToIgnoreCase(inL[i + 1]) < 0)
{
temp = inL[i];
inL[i] = inL[i + 1];
inL[i + 1] = temp;
}
}
return inL; // returns sorted array
} // end bubbleSort method
You compare passNum instead of i against the length of the array. Since passNum is never modified, the loop condition is always true, and i gets incremented until it exceeds the range of the array.
Even if this particular issue is resolved, you may still run into problems with off-by-one errors with your current implementation. Consider whether you should compare i against inL.length - 1.
You never increment passNum so i continues incrementing forever. Also, array indexing in Java is based at 0. That means that the largest valid index is inL.length - 1. Since the body of your loop accesses inL[i+1], you should arrange your code so that i never exceeds inL.length - 2. At a minimum, you should change <= to < in the for loop termination test. (However, the logic of your comparison and incrementing escapes me; you need to fix that as well.)
Array.length stores the total length of an array, starting counting at 1.
The first index in an array however is 0, meaning that the last index is length-1.
adjust your check in your for-loop to fix the error
Your problem is the passNum <= (inL.length) it should be passNum < (inL.length) due to 0 being the first index of an array in java

Circular increment: Which is "better"?

When you have a circular buffer represented as an array, and you need the index to wraparound (i.e., when you reach the highest possible index and increment it), is it "better" to:
return (++i == buffer.length) ? 0: i;
Or
return ++i % buffer.length;
Has using the modulo operator any drawbacks? Is it less readable than the first solution?
EDIT:
Of course it should be ++i instead of i++, changed that.
EDIT 2:
One interesting note: I found the first line of code in ArrayBlockingQueue's implementation by Doug Lea.
Update: OP has admitted in a comment that it should have been pre-increment instead. Most of the other answers missed this. There lies proof that the increment in this scenario leads to horrible readability: there's a bug, and most people couldn't see it.
The most readable version is the following:
return (i == buffer.length-1) ? 0 : i+1;
Using ++ adds unnecessary side effect to the check (not to mention that I strongly feel that you should've used pre-increment instead)
What's the problem with the original code? Let's have a look, shall we?
return (i++ == N) ? 0 : i; // OP's original, slightly rewritten
So we know that:
i is post-incremented, so when i == N-1 before the return statement, this will return N instead of wrapping to 0 immediately
Is this intended? Most of the time, the intent is to use N as an exclusive upper bound
The variable name i suggests a local variable by naming convention, but is it really?
Need to double check if it's a field, due to side-effect
In comparison:
return (i == N-1) ? 0 : i+1; // proposed alternative
Here we know that:
i is not modified, doesn't matter if it's local variable or field
When i == N-1, the returned value is 0, which is more typical scenario
The % approach
Alternatively, you can also use the % version as follows:
return (i+1) % N;
What's the problem with %? Well, the problem is that even though most people think it's the modulo operator, it's NOT! It's the remainder operator (JLS 15.17.3). A lot of people often get this confused. Here's a classic example:
boolean isOdd(int n) {
return (n % 2) == 1; // does this work???
}
That code is broken!!! It returns false for all negative values! The problem is that -1 % 2 == -1, although mathematically -1 = 1 (mod 2).
% can be tricky, and that's why I recommend the ternary operator version instead. The most important part, though, is to remove the side-effect of the increment.
See also
Wikipedia: modulo operation
Don't ask me to choose between two options which both contain postincrement (*) mixed with expression evaluation. I'll say "none".
(*) Update: It was later fixed to preincrement.
Wouldn't the i++ % buffer.length version have the drawback that it keeps incrementing i, which could lead to it hitting some sort of max_int/max_long/max_whatever limit?
Also, I would split this into
i = (i++ == buffer.length) ? 0 : i;
return i;
since otherwise you'd most likely have a bug.
The first one will give you an ArrayIndexOutOfBoundsException because i is never actually reset to 0.
The second one will (probably) give you an overflow error (or related undesirable effect) when i == Integer.MAX_VALUE (which might not actually happen in your case, but isn't good practice, IMHO).
So I'd say the second one is "more correct", but I would use something like:
i = (i+1) % buffer.length;
return i;
Which I think has neither of the two problems.
I went ahead and tested everyone's code, and was sad to find that only one of the previous posts (at the time of this post's writing) works. (Which one? Try them all to find out! You might be surprised!)
public class asdf {
static int i=0;
static int[] buffer = {0,1,2};
public static final void main(String args[]){
for(int j=0; j<5; j++){
System.out.println(buffer[getIndex()]);
}
}
public static int getIndex(){
// return (++i == buffer.length) ? 0: i;
// return ++i % buffer.length;
// i = (i++ == buffer.length) ? 0 : i;
// return i;
// i++;
// if (i >= buffer.length)
// {
// i = 0;
// }
// return i;
// return (i+1 == buffer.length) ? 0 : i+1;
i = (i+1) % buffer.length;
return i;
}
}
Expected output is:
1
2
0
1
2
Apologies in advance if there's a coding error on my part and I accidentally insult someone! x.x
PS: +1 for the previous comment about not using post-increment with equality checks (I can't actually upmod posts yet =/ )
I prefer the condition approach even if we use unsigned type, modulo operation has drawbacks. Using modulo has a bad side effect when the number tested rolls back to zero
Example:
255 % 7 == 3
So if you use byte (unsigned char) for example, when the number roll after 255 (i.e. zero), it will not result to 4. Should result to 4 (when 256 % 7), so it rotates correctly. So just use testing(if and ternary operator) constructs for correctness
If for achieving performance, and if the number is multiple of 2 (i.e. 2, 4, 8, 16, 32, 64, ...), use & operator.
So if the buffer length is 16, use:
n & 15
If buffer length is 64, use 63:
n & 63
Those rotate correctly even if the number goes back to zero. By the way, if the number is multiple of 2, even the modulo/remainder approach would also fit the bill, i.e. it will rotate correctly. But I can hazard a guess that & operation is faster than % operation.
I think the second solution has the clear advantage that it works, whereas the first does not. The first solution will always return zero when i becomes bigger than buffer.length because i is never reset.
The modulo operator has no drawbacks.
Surely it would be more readable to use an if:
i++;
if (i >= buffer.length)
{
i = 0;
}
return i;
Depends a bit if buffer.length ever changes.
This is very subjective and depends on what your colleagues are used to see. I would personally prefer the first option, as it expresses explicitly what the code does, i.e. if the buffer length is reached, reset to 0. You don't have to perform any mathematical thinking or even know what the modulo does (of course you should! :)
Personally, I prefer the modulo approach. When I see modulo, I immediately think of range limiting and looping but when I see the ternary operator, I always want to think more carefully about it simply because there are more terms to look at. Readability is subjective though, as you already pointed out in your tagging, and I suspect that most people will disagree with my opinion.
However, performance is not subjective. Modulo implies a divison operation which is often slower than a comparison against zero. Obviously, this is more difficult to determine in Java since we're not compiling to native code until the jitter kicks in.
My advice would be write which ever you feel is most appropriate (so long as it works!) and get a colleague (assuming you have one) to asses it. If they disagree, ask another colleague - then go with the majority vote. #codingbydemocracy
It is also worth noting, that if our buffer has length of power of 2 then very efficient bit manipulation will work:
idx = (idx + 1) & (length - 1)
You can use also bit manipulation:
idx = idx & ((idx-length)>>31)
But it's not faster than the if-variant on my machine.
Here is some code to compare running time in C#:
Stopwatch sw = new Stopwatch();
long cnt = 0;
int k = 0;
int modulo = 10;
sw.Start();
k = 0;
cnt = 0;
for ( int j=0 ; j<100000000 ; j++ ) {
k = (k+1) % modulo;
cnt += k;
}
sw.Stop();
Console.WriteLine( "modulo cnt=" + cnt.ToString() + " " + sw.Elapsed.ToString() );
sw.Reset();
sw.Start();
k = 0;
cnt = 0;
for (int j = 0; j < 100000000; j++) {
if ( ++k == modulo )
k = 0;
cnt += k;
}
sw.Stop();
Console.WriteLine( "if cnt=" + cnt.ToString() + " " + sw.Elapsed.ToString() );
sw.Reset();
sw.Start();
k = 0;
cnt = 0;
for (int j = 0; j < 100000000; j++) {
++k;
k = k&((k-modulo)>>31);
cnt += k;
}
sw.Stop();
Console.WriteLine( "bit cnt=" + cnt.ToString() + " " + sw.Elapsed.ToString() );
The Output:
modulo cnt=450000000 00:00:00.6406035
if cnt=450000000 00:00:00.2058015
bit cnt=450000000 00:00:00.2182448
I prefer the modulo operator for the simple reason it is shorter. And any program should be able to dream in modulo since it is almost as common as a plus operator.

Categories