Your code is properly formatted (except for one superfluous space), however, the lengthy expression
((a == b + 1 || a == b - 1) || (a == c + 1 || a == c - 1)) && ((b == c + 1 || b == c - 1))
|| ((b == c + 1 || b == c - 1) || (a == b + 1 || a == b - 1)) && (a == c + 1 || a == c - 1)
is pretty hard to read. The best solution is to use either sorting or something smart as 200_success or rolfl proposed. I try an advice for the case that no such solution is available.
Note that you're doing something like
if (x) {
return false;
} else if (y) {
return true;
}
return false;
This is actually always sort of wrong as you can do
if (x) {
return false;
} else {
return y;
}
instead. You can also leave out the "else", but that's matter of style.
As your lengthy condition is a disjunction and the action is trivial, you can simply split it like
if (x) {
return false;
} else if (y1) {
return true;
} else if (y2) {
return true;
}
return false;
Here, I avoided my above simplification to preserve symmetry.
Let's look at the part denoted as y1
, i.e.,
((a == b + 1 || a == b - 1) || (a == c + 1 || a == c - 1)) && ((b == c + 1 || b == c - 1))
now. The first part states that the distance of a
and b
is 1
, in other words Math.abs(a - b) == 1
. You can use it to make your conditions slightly less repetitive.
More importantly, observe the same expression appear later again, define some local variables to keep it short (with or without abs
; the idea is independent):
if (a == b || b == c || a == c) {
return false;
}
boolean ab = a == b + 1 || a == b - 1;
boolean bc = b == c + 1 || b == c - 1;
boolean ac = a == c + 1 || a == c - 1;
return (ab | ac) & bc || (bc | ab) & ac;
My above naming is not the best, however, I consider it acceptable as the scope is very limited. Still, because of the asymmetry, it's a bit hard to tell if it's right.
You could rewrite it as
return ab & bc | ab & ac | bc & ac;
Another simplification is possible by observing that shifting all value by the same distance doesn't change anything. So you could do something like
a -= c;
b -= c;
c -= c; // i.e., c = 0
and simplify the other expression a bit. This isn't worth it here. By using the arithmetic, you make yourself susceptible to overflow just like here.
To add something funny, I propose this
public static boolean consecutive(int a, int b, int c) {
return 2 ==
+ (Math.abs(a - (long) b) == 1 ? 1 : 0)
+ (Math.abs(b - (long) c) == 1 ? 1 : 0)
+ (Math.abs(a - (long) c) == 1 ? 1 : 0);
}
It works simply by requiring exactly two of the distances to equal one. The case to long prevents overflow (and may be left out if you don't mind wrapping around Integer.MAX_VALUE
).