I have booleans A, B, C, D set to false.
I have following code if (A && B || C && D) {Debug.i("Check", "stars")}
When will I get "stars" message?
When A and B OR C and D set to true.
When A, B/C, D set to true
=============================
ANSWER
A && B || C && D
should be treated as
(A && B) || (C && D)
Boolean order of operations is the following:
Parentheses
NOT
AND
OR
So you are right in your examples.
You will get the "stars" message when both A and B are set to true OR C and D are set to true.
Related
I was wondering how to check if two out of three values are the same. My code right now is:
public static boolean twoOutOfThree(int a, int b, int c) {
if ((a == b) || (b == c) || (a == c)) {
return true;
}
return false;
}
This passes all of the tests that are true however when I test it for (0,0,0), it comes back as true instead of false. Any suggestions on what I'm doing wrong?
When all 3 are the same, then a == b obviously is also true. So each 3 of the cases also needs to check that the 3rd one is different. So you need to change
(a == b || b == c || a == c)
to
(a == b && b != c) || (b == c && a !=c ) || (a == c && b != c))
Additional tip
Functions of this form:
if (condition) {
return true;
} else {
return false;
}
Can be written much shorter by just doing
return condition;
So the end result is this:
public static boolean twoOutOfThree(int a, int b, int c) {
return ((a == b && b !=c ) || (b == c && a !=c ) || (a == c && b !=c));
}
Here is a non-optimized solution.
The Set will get rid of duplicates, then just check its final size.
return new HashSet<Integer>(Arrays.asList(a,b,c)).size() == 2;
You could add an extra case to your if statement:
((a==b) || (b==c) || (a==c) && !(a == b & b == c))
There is probably a more efficient way to do this.
You can add a variable called "count" for example , if any value is equal to another then you increment the count by 1 and then you can check if count is equal to 2
You can count as the following solution
public static boolean twoOutOfThree(int a, int b, int c) {
int count = 0;
if (a == b) {
count += 1;
}
if (b == c) {
count += 1;
}
if (c == a)
count += 1;
}
if (count == 2) {
return true;
} else {
return false;
}
}
Just create a Set and add your values in the set. Set always holds unique values only. So if you have 3 numbers and add them to a set and your set length is 3 that none of the numbers are equal to each other. If the length is 2 then 2 numbers where equal and if the length is 1 then all 3 are equal
return !(
(
(a==b)&&(b==c)
) ||
(
(a!=b)&&(b!=c)&&(a!=c)
)
);
Only 10 operators made of
3 AND
1 OR
1 NOT
5 comparisons
I don't know if this is fastest. But if CPU core has multiple ALUs each doing comparisons in parallel, then this could get a boost.
For this expression :
((a == b && b == c) && (a == b || b == c || a == c))
Is it legal to write it like below :
(a == b && b == c && a == b || b == c || a == c)
I want to compare the first set with the second set.
a, b and c are integers :
private int a;
private int b;
private int c;
No, it is not. && is associative: A && B && C is the same as A && (B && C) and (A && B) && C, and || is as well: A || B || C is the same as A || (B || C) and (A || B) || C.
However, it does not work when two different operations are involved: (A && B) || C is very different from A && (B || C). Furthermore, since && binds more tightly than ||, A && B || C is the same as the former, and different from the latter.
Thus, your first example
((a == b && b == c) && (a == b || b == c || a == c))
is equivalent to
(a == b && b == c && (a == b || b == c || a == c))
but your second example
(a == b && b == c && a == b || b == c || a == c)
is equivalent to a something completely different:
((a == b && b == c && a == b) || b == c || a == c)
(As Kayaman notes in the comments, it is irrelevant in this particular example, since all of them can be reduced to just (a == b && b == c), by the virtue of specific predicates used in your example; thus, while they are identical in this particular example, you should still understand the concepts of associativity and precedence to be used in general.)
It is legal, but it has a different meaning.
Since && has higher priority than || and operators associate from left to right your second example is parsed as
((a == b && b == c) && a == b) || b == c || a == c
AND (&&) operator has a higher precedence than OR (||) operator. This means that last comparison expressions:
b == c
a == c
will be computed after first half of your expression. After that OR operators will be calculated. So, yes it is legal in your case, but will return different answer.
Your condition will be computed as follows:
((a == b && b == c) && a == b) || b == c || a == c
I have a conditional if statement like this
if ((a && (b || c)) ||
(b && (a || c))) {
}
basically what I'm trying to achieve is that I can only have one option true, but two is not ok!
Can it be more simplified, looks redundant to me!
Or should I extract it to a function?
edit
if (a && !b && !c) // process a
if (b && !a && !c) // process b
if (c && !a && !b) // process c
if (!a && !b && c!) // none present exception
else {} // more than one case exception
Yes it can be simpler, this would be more than enough since a && b will give the same result as b && a:
if (a && b || c) {
}
Note: the original question was completely different, and asked to simplify the following expression:
if ((a && b || c) ||
(b && a || c)) {
}
Following the comment and the edit, each line is the development of the previous one:
(a && (b || c)) || (b && (a || c))
((a && b) || (a && c)) || ((a && b) || (b && c))
(a && b) || (a && c) || (a && b) || (b && c)
You have a duplicate, so you can turn it to: (those lines are equals)
(a && b) || (a && c) || (b && c)
(a && (b ||c)) || (b&&c)
&& operator is Commutative so a && b or b && a results in same output.
Now your condition becomes like this
if ((a && b || c) ||
(a && b || c)) {
}
|| operator is Idempotent so x || x results x
your expression becomes (a && b) || c
But in java && and || operators exhibit "short-circuiting" behavior
First operand will be evaluated first and then second operand will be evaluated only if need so you can choose which operand to keep first based on operand complexity.
if (c || (a && b) {
...
}
The 2 large conditions are the same... ยด&&` is commutative
boolean a = true
boolean b = true
<random code in here, booleans may or may not change>
if ((!a || !b) || (!a && !b)){
doSomethingElse();
}
This code is not working for me, what is a simple solution to this problem?
To be clear:
The if statement should work:
if at least one of the booleans is false
3 cases:
a = False b = True
a = True b = False
a = False b = False
I could do this in one long if statement, but I was just wondering if there was a simple way to implement this.
This should work for you:
if( !a || !b ) {
doSomething();
}
if(!(a && b)) {
....Then do something
}
(Way too much time, breakdown of logic)
Start by applying De Morgan's to get the ! outside: (Although other boolean algebra could be applied at this stage to skip a few steps, I like to show this.)
That is, given:
(!a || !b) (by DM) -> !(a && b) and
(!a && !b) (by DM) -> !(a || b).
Then (!a || !b) || (!a && !b) (by substituion) -> !(a && b) || !(a || b).
Applying DM again:
!( (a && b) && (a || b) )
Now using "distributivity of ^ over v" (x = a && b; y = a; z = b):
!( ((a && b) && a) || ((a && b) && b) )
And by "associativity" and "communicativity":
!( (a && a && b) || (a && b && b) )
And by "idempotence":
!( (a && b) || (a && b) )
!( (a && b) )
Simplified:
!(a && b)
Back by DM:
!a || !b
Of course, a simple Truth Table may have been easier to show this ..
Your if statement will work just change your if Statement to this:
if (!a || !b) {
}
As you can see above it will work when any one of the boolean is false .
All the Best.
Your proposed solution can be simplified to...
if (!a || !b) { .... }
By checking whether one is false or both are false, you're making sure that both are true, or a && b. The opposite of a && b is !a || !b:
if (!a || !b) {
doSomethingElse();
}
if (!(a && b)) {
doSomethingElse();
}
I have a java program where I want to validate if any of 3 booleans is false. I want to figure out the smallest expression I can write to check against the permutations.
if(!(needsWork && (needsApproval || isAdmin) ))
I think this is enough to make sure that if any of the 3 booleans is false I want to stop processing. However, I have the sneaking suspicion I am missing something.
Would if (!needsWork || !needsApproval || !isAdmin) not work? Java supports short-circuit evaluation.
Since
`any 3 booleans are false` (i.e. `!a || !b || !c`)
and
`(! (needsWork && (needsApproval || isAdmin))` (i.e. (! (a && ( b || c))`
have different truth tables, are you sure that the cases that are different don't matter?
a b c (!a || !b || !c) (! (a && (b || c)))
T T T F F
T T F T F
T F T T F
T F F T T
F T T T T
F T F T T
F F T T T
F F F T T
Transformations
I will often play around with boolean expressions to try to clarify or simplify them and I use these logic transformations to help me:
// You can push (distribute) `!` into parenthesis if you reverse the `||` or `&&` operator inside:
! (a || b) <=> (! a && ! b)
! (a || b || c || ...) <=> (! a && ! b && ! c && ...)
! (a && b) <=> (! a || ! b)
! (a && b && c && ...) <=> (! a || ! b || ! c || ...)
// You can drop parens when the boolean operator outside the parens is the same as inside:
(a || (b || c || ...)) <=> (a || b || c)
(a && (b && c && ...)) <=> (a && b && c)
// You can push (distribute) a boolean op into parenthesis by applying it to each term inside:
(a || (b && c) <=> ((a || b) && (a || c)
(a || (b && c && ...) <=> ((a || b) && (a || c) && (a || ...) ...
(a && (b || c) <=> ((a && b) || (a && c))
(a && (b || c || ...) <=> ((a && b) || (a && c) || (a || ...) ...
// XOR means the term values have to be different:
(a ^ b) <=> ((a && !b) || (!a && b))
// XOR means the same as OR unless both terms are true:
(a ^ b) <=> ((a || b) && ! (a && b))
There are of course many others, but these are ones I use most often. It may look complicated, but they are easy to get to know by heart once you start by practicing them.
In your case, if you wanted to see what some possible equivalent statements for:
(! (needsWork && (needsApproval || isAdmin) ))
here are some transformations:
(! (needsWork && (needsApproval || isAdmin) )) => [push the '!' through the `()`]
(! needsWork || ! (needsApproval || isAdmin) ) => [push the 2nd '!' through the `()`]
(! needsWork || (! needsApproval && ! isAdmin))
but I don't see any real simplification of what you have.
Of course, if checking that any of 3 booleans are false is fine, then your choices are simple
(! needsWork || ! needsApproval || ! isAdmin) => [or pull the `!` outside the `()`]
(! (needsWork && needsApproval && isAdmin))
if(!(needsWork & needsApproval & isAdmin))