Reputation: 1173
There is a puzzle on codingbat.com that seemed quite trivial but when I solved it and submitted, it was marked wrong when the argument 45 or 15 was passed in to the method. What am I doing wrong here in my logic to the following question?
Return true if the given non-negative number is a multiple of 3 or 5, but not both. Use the % "mod" operator -- see Introduction to Mod
My solution:
public Boolean old35(int n) {
if( n % 3 == 0 || n % 5 == 0 && !(n % 3 == 0 && n % 5 == 0) ){
return true;
}
return false;
}
Codingbat's solution that makes no sense to me at all:
public Boolean old35(int n) {
return n % 3 == 0 ^ n % 5 == 0;
}
Upvotes: 2
Views: 1946
Reputation: 11
return (n%3 == 0 || n%5 == 0) && !(n%3 == 0 && n%5 == 0);
You can check both conditions and then pass the results of those conditions through an AND gate (&&).
Upvotes: 1
Reputation: 178263
The &&
operator takes precedence over ||
, so it takes place after !(n % 3 == 0 && n % 5 == 0)
but before the or ||
. With 45
, it's true that it's a multiple of 3
and 5
, so the !
returns false
. It's a multiple of 5
, so true & false
yields false
. It's a multiple of 3
, so true
or false
yields true
, which is incorrect according to the requirements.
You can correct your solution by inserting parentheses to force the ||
before the first &&
:
// v v
if( ( n % 3 == 0 || n % 5 == 0 ) && !(n % 3 == 0 && n % 5 == 0) ){
Codingbat's solution uses the XOR operator, ^
. This operator means either one or the other is true, but not both, which fits the requirements exactly. Also, there is no reason for the if
; you can return the boolean expression directly.
Upvotes: 6
Reputation: 37645
Your solution is almost right. You just need brackets:
if((n % 3 == 0 || n % 5 == 0) && !(n % 3 == 0 && n % 5 == 0) )
Without brackets it is treated as
if( n % 3 == 0 || (n % 5 == 0 && !(n % 3 == 0 && n % 5 == 0)) )
^
is exclusive or. x ^ y
means either x
or y
is true, but not both.
Upvotes: 2