I was just surprised by the very short Java 8 solution by mjolka, so I'm giving it a try in Java 7.
public double percentEven(int[] values) {
int even = 0;
for (int x : values) even += 1 - (x & 1);
return 100.0 * even / values.length;
}
I violated the braces-everywhere convention in order to save 2 lines, but this is still not good enough. Java 8 still wins by 1 line, and that seems impossible to beat.
OTOH the Java 8 solution produces some garbage and I'm afraid it's one or two orders of magnitude slower.
Reaction to comments
To those thinking that the following would be clearer
even += (x%2 == 0 ? 1 : 0);
No, it wouldn't. The former is hard to understand for people unfamiliar with bitwise operation, the latter is hard to understand for people unfamiliar with ternary expressions. While bitwise operations are a bit more exotic, it makes no sense to reduces everyone's capabilities to the lowest common denominator. It's no hack, no magic, no code golf, just learn it!
Once we know that x & 1
extracts the lowest binary digit, we could even argue that it's much cleaner than a conditional expression.
Note on optimizations
Division and modulus are pretty expensive and JIT is pretty smart on optimizing them. However, x % 2
is not the same as x & 1
for negative numbers, so more work has to be done, see this answer for some benchmarks.
OTOH x % 2 == 0
is the same as (x & 1) == 0
, but I don't know if JIT uses this fact.
A maximally optimized code could look like this
public double percentEven(int[] values) {
int even = values.length;
for (int x : values) even -= x & 1;
return 100.0 * even / values.length;
}
Problems with modulus
Using modulus is a bit error prone as both
even += x%2 == 1 ? 0 : 1;
and
even += 1 - x%2;
are wrong. The problem is that %
for negative numbers does not do what we usually need (i.e., rounding towards negative infinity rather than rounding towards zero).