Consider the following:
if ((a || b) && (c || d))
{
if (a && c) {...}
else if (b && d) {...}
else {...}
}
else {...}
where a, b, c and d are expressions that result in a bool.
As is clear from the code, few of these expressions are being recalculated. Is there a better approach in terms of a) clarity? b) Efficiency?
Surprise: I don't think you really need the outer if statement. Appreciate that using the laws of logic the outer if can be rewritten from:
if ((a || b) && (c || d))
to
if ( ((a && c) || (a && d)) || ((b && c) || (b && d)) )
In other words, if (a && c) or (b && d) be true, then the outer if will always evaluate to true, so it can be dropped. Instead, you could write this:
if (a && c) {...}
else if (b && d) {...}
else if ((a && d) || (b && c)) {...} // your original 'inner' else
else {...} // your original 'outer' else
Trivial answer: You can store the expressions in bool variables before the if statements.
If the expressions do not involve function calls (and thus it is clear that they may not change in between the statements), I would expect the compiler to optimise it like this anyway.
Related
this is the problem https://www.urionlinejudge.com.br/judge/en/problems/view/1042
and the code
#include <iostream>
using namespace std;
int A,B,C
int main ()
{
cin >> A >> B >> C;
if (A > B > C)
cout <<C<<"\n"<<B<<"\n"<<A<<"\n\n";
else if (B > A > C)
cout <<C<<"\n"<<A<<"\n"<<B<<"\n\n";
else if (C > A > B)
cout <<B<<"\n"<<A<<"\n"<<C<<"\n\n";
else if (A > C > B)
cout <<B<<"\n"<<C<<"\n"<<A<<"\n\n";
else if (C > B > A)
cout <<A<<"\n"<<B<<"\n"<<C<<"\n\n";
else {
(B > C > A);
cout <<A<<"\n"<<C<<"\n"<<B<<"\n\n";}
cout <<A<<"\n"<<B<<"\n"<<C<<endl;
return 0;
}
Your main problem is that if(A > B > C) becomes if (A > (B > C)) - in other words, you're comparing A to the true or false result of B > C, which will be true for all values where A of 2 or greater, regardless of the values of B and C.
The fix is to compare A > B separately from B > C, so use if (A > B && B > C) or some similar construct.
You have to trnasform things like:
(A > B > C)
into:
(A>B && B>C)
Conditions in the if statements are wrong. For example condition
if (A > B > C)
is equivalent to
if ( ( A > B ) > C)
In this case condition ( A > B ) is evaluated to either true or false and the condition is equivalent to either to
if ( true > C)
or
if ( false > C)
It is obvious that it is not what you want to get.
So the original condition has to be rewritten like
if (A > B && B > C )
But even in this case the program will be wrong because it does not consider cases when the variables could be equal each other. So the valid condition will look like
if (A >= B && B >= C )
And the program will not compile because at least here there is a typo
int A,B,C
^^^
You forgot to place a semicolon
int A,B,C;
Also there is no sense to declare variables A, B, C as global
int A,B,C;
int main ()
{
//...
It is better to declare them as local variables of function main
int main ()
{
int A, B, C;
//...
And this code snippet is wrong
else {
(B > C > A);
cout <<A<<"\n"<<C<<"\n"<<B<<"\n\n";}
cout <<A<<"\n"<<B<<"\n"<<C<<endl;
I think you mean simply
else cout <<A<<"\n"<<C<<"\n"<<B<<endl;
I have following loop as a inner loop and try to get rid of it by transforming it into a mathematical formula:
while(!(((aux = a * b) <= c) && (c >= aux + d))) --a;
a, b, c, d and aux are all of type size_t, i.e. unsigned int's
NOTE: a is decremented in every iteration within the loop's body!
I'm totally stuck at this problem. I tried to simplify the loop condition, but failed because of the unsignedness constraint.
As result I just want to get the value of a depending on b, c, d.
Replace aux with a*b at every point, and you get:
!(a * b <= c && c - a * b >= d)
<=> !(a * b <= c && c >= d + a * b)
<=> !(a * b <= c && d + a * b <= c)
If d is greater than c, the second condition will be false and therefore the loop will never terminate. So we can consider only d <= c. The second condition is stricter, so we can focus on that solely:
<=> !(d + a * b <= c)
<=> !( a * b <= c - d)
<=> !( a <= (c - d)/b) // if integer division is used
<=> ( a > (c - d)/b)
Given that you only decrement a, it either needs to fulfil the condition (a <= (c - d)/b) right from the beginning or be less than or equal to (c - d)/b. Overall we get:
a = std::min(a, (c - d)/b);
Let's simplify:
while(!(((aux = a * b) <= c) && (c - aux >= d))) --a;
Drop aux in favor of just a*b:
while(!((a*b <= c) && (c - a*b >= d))) --a;
Rewrite the !(x && y) into !x || !y:
while ((a*b > c) || (c - a*b < d)) --a;
Flip the sign on the second expression:
while ((a*b > c) || (a*b > c - d)) --a;
Which is just:
while (a*b > min(c, c-d)) --a;
Which is to say, find the smallest a such that a*b <= min(c, c-d). Unless it's already smaller than that. So:
a = min(a, min(c, c-d) / b);
Er, given that all the variables are unsigned, obviously min(c, c-d) == c - d, so:
a = min(a, (c-d)/b);
here's a simple logic error I can't quite wrap my head around:
Why does the following statement always equate to true?
if ( (grid[i][0] && grid[i][1] && grid[i][2]) == ('X' || 'x') ) return true;
It works flawlessly for
if ( (grid[i][0] && grid[i][1] && grid[i][2]) == ('X') return true;
Do it like this:
create a function to check a character of being x:
bool isX(char c)
{
return c == 'X' || c == 'x';
}
and the you can write:
if ( isX(grid[i][0]) && isX(grid[i][1]) && isX(grid[i][2]))
return true;
That's because the expressions
'X' || 'x'
and
grid[i][0] && grid[i][1] && grid[i][2]
use the || and && operators between non-zero integer-typed values (because char is an integer type) and so they both evaluate to true.
To translate into C++ (or almost any other somewhat similar language, for that matter) that you want characters x, y and z to be equal to either of the characters c and C, you must compute
(x == c || x == C) && (y == c || y == C) && (z == c || z == C)
so apply that to your problem.
More importantly though, learn about boolean operators and programming in general before you try to tackle C++.
In the first case, it returns true because none of the grid elements has the value of zero. The && operator produces 0 or 1, depending on the values that you pass.
In the second case, it does not work as expected either: you wouldn't get an 'X' by &&-ing values together.
The proper way of checking if three items are equal to 'X' or not would be as follows:
if (toupper(grid[i][0]) == 'X'
&& toupper(grid[i][1]) == 'X'
&& toupper(grid[i][2]) == 'X') {
return true;
}
To generalize the concept of "win" in TiCTacToe, write a function that returns true when a sequence of three items with a specific step in each direction holds a sequence of a given character, like this:
bool isWin(int r, int c, int dr, int dc, char ch) {
return toupper(grid[r+0*dr][c+0*dc] == ch
&& toupper(grid[r+1*dr][c+1*dc] == ch
&& toupper(grid[r+2*dr][c+2*dc] == ch;
}
bool isWin(char ch) {
return isWin(0,0,0,1,ch)
|| isWin(0,0,1,0,ch)
|| isWin(1,0,0,1,ch)
|| isWin(0,1,1,0,ch)
|| isWin(2,0,0,1,ch)
|| isWin(0,2,1,0,ch)
|| isWin(0,0,1,1,ch)
|| isWin(2,0,-1,1,ch);
}
I am just wondering in C or C++, for the expression:
b == c || b == d
Can I do something like:
b == (c || d)
and get the same behavior?
The first expression
b == c || b == d will give you true if b is equal to either c or d.
The second expression
b == (c || d) will check only if b is either equal to 0 or 1 because the output of c || d is binary.
Consider this code:
#include <iostream>
using namespace std;
int main() {
int b=10,c=9,d=10;
cout << (b ==c || b ==d )<<endl;
cout<< ( b == ( c || d)) <<endl;
d=11;
cout << (b ==c || b ==d )<<endl;
cout<< ( b == ( c || d)) <<endl;
return 0;
}
The output is
1
0
0
0
Now you can clearly see that both expressions are not same.
No, operators in C and C++ don't implicitly distribute over subexpressions like that. Evaluation is defined strictly in terms of the direct association of operators with operands. There are no "shortcuts" as you might have in mathematics or English.
If you write code that incorrectly assume such implicit distribution, you're likely to end up with an expression that's syntactically and semantically valid, but that doesn't do what you expect.
The || operator yields a value of 1 or true if either operand is true (non-zero) or a value of 0 or false if both operands are false (equal to zero). And the operands needn't be boolean; they can be of any scalar type. (In C the result is of type int; in C++ it's of type bool.) The expression
b == c || b == d
is equivalent to
(b == c) || (b == d)
and yields a true result if b is equal to c or if b is equal to d. But this expression:
b == (c || d)
computes the value of (c || d), and the tests whether b is equal to the result of that subexpression.
A similar possible source of confusion is that
x < y < z
is not equivalent to
(x < y) && (y < z)
Rather, it's equivalent to
(x < y) < z
where the false or true (in C++) or 0 or 1 (in C) result of x < y is compared to the value of z.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
if ((x != A) || (x != a )|| ( x != B) || (x != b) || ( x != C) || (x != c) || (x != D) || (x != d) || ( x != F) || (x != f))
{
System.out.println("Points: -1");
return true;
}
else
{
System.out.println("hi");
return false;
}
For some reason I can't get this to return anything else but true.
Take the first two conditions: (x != A) || (x != a ).
What your saying here is, return true if x is either not equal to A or to a.
Assuming x == A, the first condition will return false and the second true. Thus your whole if-condition will return true.
Likewise for x == a. Here the first condition yields true and so does the if-condition.
What you probably mean is to connect all those conditions using AND or && instead of OR (||).
if ((x != 'A') || (x != 'a' ) ....
^ missing quotes
But even then, x can either be 'A' or 'a' or neither. With the OR evalution, you will always end up with TRUE as x will always NOT be one of those other values you are testing.
Do (x != 'A') && (x != 'a' ) ...
yes it will be always true
lets just concider part of your expression ((x != A) || (x != a ) ...
if x=A, then first statement is false, but other one is true, and as you have disjunction so you will always get true.
to get false you need x=A and x=a, which might be bit impossible
Check out this Fiddle http://jsfiddle.net/CtCqe/2/
Using regex might be better, not sure if the input of the user is only a single character or not.
Html
<div id="result">Result</div>
<input type='text'/>
<div id="pressed"></div>
Jquery
$('input').on('change input', function(){
var x = $(this).val();
if((x == 'A') || (x == 'a' )|| ( x == 'B') || (x == 'b') || ( x == 'C') || (x == 'c') || (x == 'D') || (x == 'd') || ( x == 'F') || (x == 'f')){
$('#result').html('False');
$(this).val('');
}else{
$('#result').html('True');
$(this).val('');
}
$('#pressed').html(x);
});