How to have an if() split by && and not || - c++

I'm trying to do something like this in c++
If x is equal to either a or b or c
and y is equal to either d or e or f
and z is equal to either g or h or i, it would turn true and execute the code
I am a bit lost in this
if(x==a||x==b||x==c && y==d||y==e||y==f && z==g||z==h||z==i){
// Do x
}

Just use && and ||, with parentheses to make the grouping clear.
if ((x == 'a' || x == 'b' || x == 'c')
&& (y == 'd' || y == 'e' || y == 'f')
&& (z == 'g' || z == 'h' || z == 'i')) {
// execute code
}

If you look at C++ operator precedence you'll find that && has higher precedence than ||.
That means that your if statement
if(x==a||x==b||x==c && y==d||y==e||y==f && z==g||z==h||z==i)
is the same as
if (x == a || x == b || (x == c && y == d) ||
y == e || (y == f && z == g) ||
z == h || z == i)
By using parentheses, you can change it to work the way you want:
if ((x == a || x == b || x == c) &&
(y == d || y == e || y == f) &&
(z == g || z == h || z == i))

It is a straightforward translation from what you said to C++ code:
if ((x == a || x == b || x == c) &&
(y == d || y == e || y == f) &&
(z == g || z == h || z == i))
{
}
Most real programs don't have conditionals this complex. Split up your logic into logical tests.

From the previous answers, the important point is that in C++, you missed that the AND operator && has a higher operator precendence than the OR operator ||.
This can be compared to how the multiplicative operators *, /, % of numbers have higher precedence than additive operators + and - in algebra.
Regroup the parathetheses so you have these three requirements of what x, y, and z have to be, and the statement is true when all three are correct. (Technically, this is called a product of sums form, as the if statement requires the truth of all three smaller statements (the AND), where each of the smaller statement uses only OR statements.).
if((x==a||x==b||x==c) && (y==d||y==e||y==f) && (z==g||z==h||z==i)){
// Do x
}
Your original code would be equivalent to
if(x==a || x==b || (x==c && y==d) || y==e || (y==f && z==g) || z==h || z==i){
// Do x
}
For larger if-statements, you can also use newlines but of course that will take up more lines.
if((x==a||x==b||x==c)
&& (y==d||y==e||y==f)
&& (z==g||z==h||z==i)
&& ... other conditions)){
// Do x
}
If you do not want such cumbersome and long if-statement notation, you can consider breaking into logical tests (the if-condition is the "product" of the logical tests), namely
bool a1 = (x==a||x==b||x==c);
bool a2 = (y==d||y==e||y==f);
bool a3 = (z==g||z==h||z==i);
bool a4 ...
if (a1 && a2 && a3 && a4 && ..) {
// Do x
}

Try using parentheses to separate your questions:
if( (condA || condB || condC) && (condD || condE || condF) && (...)) and so on.
(condA = condition A)

Going a little overboard here (but just a bit):
if (element_of(x, {a, b, c}
&& element_of(y, {d, e, f})
&& element_of(z, {g, h, i}))
{
foo();
}
with element_of defined as:
template <class T>
auto element_of(const T& element, std::initializer_list<T> list) -> bool
{
return std::find(list.begin(), list.end(), element) != list.end();
}
Or a even a little bit more overboard (this is just for fun, I don't recommend it):
if (Elem{x}.element_of({a, b, c})
&& Elem{y}.element_of({d, e, f})
&& Elem{z}.element_of({g, h, i}))
{
foo();
}
with Elem:
template <class T> struct Elem
{
T element;
auto element_of(std::initializer_list<T> list) -> bool
{
return std::find(list.begin(), list.end(), element) != list.end();
}
};
template <class T> Elem(T) -> Elem<T>;

Related

How to make a loop to determine if 2 numbers belong in a given range

I am having problems making a loop which stops when both x and y are in the range/interval [0,1] in c++.
double x;
double y;
while(condition)
{
if(x < 0)
{
x = -x;
}
else
{
x = 2 - x;
}
if(y < 0)
{
y = -y;
}
else
{
y = 2 - y;
}
}
This method with 2 loops works:
while((x < 0) || (x > 1)) {do sth}
while((y < 0) || (y > 1)) {do sth}
This doesn't work:
while(!((x >= 0) && (x <= 1)) && !((y >= 0) && (y <= 1))) {do sth}
And this doesn't work either:
while(((x < 0) || (x > 1)) && ((y < 0) || (y > 1))) {do sth}
This makes an infinite loop (in my case):
while(((x < 0) || (x > 1)) || ((y < 0) || (y > 1))) {do sth}
Note: {do sth} changes x and y if needed so they will eventually go in that interval (same as in the first block of code).
Note 2: By doesn't work I mean it never goes in the loop when x is in the interval and y < 0 (and some other cases).
while ( !( (x>=0 && x<=1) && (y>=0 && y<=1) ) ) should be the combined conditional check.
I'd go for a dedicated function with a speaking name: so you can still understand your code in a couple of weeks :-), e.g.
auto check_outside_interval_0_1 = [] (double const a) {
return a < 0.0 or 1.0 < a;
};
while( check_outside_interval_0_1(x) or
check_outside_interval_0_1(y) ) {
// ... do your things here
}

Optimize/Reduce condition expression in if statement

The goal is to optimize big condition expression by finding values dependencies between variables in order to reduce the logical OR statements.
Let's say we have the following condition:
if((A == 0 && B == 0) || (A == 0 && B == 1) || (A == 0 && B == 2) ...
a certain number of time...
Is there a way to reduce this kind of example by having automatically the following condition:
if(A == 0 && (B >= 0 && B <= 2))
The numbers involved in the first condition are only known just before the condition, it can't be typed manually. There can be also hundreds of logical OR operators involved in the condition. There can be gap between values (maybe use of % operator is needed) but there is always a pattern.
Any library or existing algorithm which can find the dependencies between the variables ?
Let's have another example:
if((A == 0 && B == 0) || (A == 0 && B == 2) || (A == 0 && B == 4)
can be translated to:
if((A == 0 && B%2 == 0)
One more:
if((A == 0 && B == 0 && C == 0) || (A == 0 && B == 2 && C == 0) || (A == 0 && B == 4 && C == 0) || (A == 0 && B == 0 && C == 1) || (A == 0 && B == 2 && C == 1) || (A == 0 && B == 4 && C == 1))
would be transformed into:
if(A==0 && B%2==0 && C>=0 && C<=1)
For the variables involved, I have all the values per terms.
I have something like [[0,0,0],[0,2,0],[0,4,0],[0,0,1],[0,2,1],[0,4,1]] (e.g. the last example)
Thanks for your time and answers !
if((A == 0 && B == 0) || (A == 0 && B == 2) || (A == 0 && B == 4)
cannot be translated to
if((A == 0 && B%2 == 0)
cuz
B == 6
and etc

What is equivalent to "!((x > y) && (y <= 0))"

What is the equivalent to the condition:
!((x > y) && (y <= 0))
Is it:
!(x > y) && !(y <= 0)
(x <= y) || (y > 0)
(x < y) || (y > 0)
After initializing the variables to make them into y = -3 and x = -3 I was able to isolate only the second one to display the same results as the first. Does this mean that this is the only one equivalent to it?
How exactly do you use truth tables or the "De Morgan's Law"?
I believe its the second one : (x <= y) || (y>0)

Query whether a char is a digit at compile time

I want to check whether a given char is a digit at compile time. In particular I need the implementation of the following function prototype:
template<char c>
constexpr bool IsDigit();
For clarification: I dont must use a custom implementation. If there is already a built-in way in the std, I would prefer that method.
This should work for ASCII:
constexpr bool IsDigit(char c) { return c >= '0' && c <= '9'; } // ASCII only
If you need to keep your prototype:
template<char C>
constexpr bool IsDigit() { return C >= '0' && C <= '9'; } // ASCII only
For wchar_t support you could try something like:
constexpr bool IsDigit(wchar_t c)
{
return (c >= L'0' && c <= L'9') ||
(c >= L'\u0660' && c <= L'\u0669') || // Arabic-Indic
(c >= L'\u06F0' && c <= L'\u06F9') || // Extended Arabic-Indic
(c >= L'\u07C0' && c <= L'\u07C9') || // NKO
(c >= L'\u0966' && c <= L'\u096F') || // Devanagari
(c >= L'\u09E6' && c <= L'\u09EF') || // Bengali
(c >= L'\u0A66' && c <= L'\u0A6F') || // Gurmukhi
(c >= L'\u0AE6' && c <= L'\u0AEF') || // Gujarati
(c >= L'\u0B66' && c <= L'\u0B6F') || // Oriya
(c >= L'\u0BE6' && c <= L'\u0BEF') || // Tamil
(c >= L'\u0C66' && c <= L'\u0C6F') || // Telugu
(c >= L'\u0CE6' && c <= L'\u0CEF') || // Kannada
(c >= L'\u0D66' && c <= L'\u0D6F') || // Malayalam
(c >= L'\u0E50' && c <= L'\u0E59') || // Thai
(c >= L'\u0ED0' && c <= L'\u0ED9') || // Lao
(c >= L'\u0F20' && c <= L'\u0F29'); // Tibetan
// Missing check for Myanmar, Khmer, Mongolian, Limbu, New Tai Lue,
// Tai Tham Hora, Tai Tham Tham, Balinese, Sundanese, Lepcha, Ol Chiki,
// Vai, Surashtra, Kayah, Javanese, Cham, Meetei Mayek, Osmanya, Brahmi,
// Sora, Chakma, Sharada, Takri, Mathematical.
// For codes see http://www.unicode.org/ucd/
}

Best way to format the conditional checks in "if" statement

This code looks dirty and I can't figure out how to format it so that I can read it, understand it, and look clean at the same time.
if(center==2 && ((((y-height/2)==j) && ((x+width/2)==i)) || (((y+height/2)==j) && ((x+width/2)==i))))
regenerateDot(i+1, j, dots);
Any suggestions?
I would break down the boolean expressions into variables named for readability. Something like:
bool isCentered = center == 2;
bool inLowerRegion = (y-height/2) == j && (x+width/2) == i;
bool inUpperRegion = (y+height/2) == j && (x+width/2) == i;
bool inEitherRegion = inLowerRegion || inUpperRegion;
if (isCentered && inEitherRegion) {
regenerateDot(i+1, j, dots);
}
Consider refactoring. You could put sub expressions into their own functions, thus naming their purpose.
For example:
if (IsCentered(center) && IsInsideLower(y, j, i) && IsInsideUpper(y, j, i))
regenerateDot(i + 1, j, dots);
Note that in the above example the function names might be bogus (I haven't really attempted to understand what the purpose of the code is), but you should get the picture.
Almost all the parenthesis are redundant... and adding some whitespace it becomes:
if(center == 2 &&
(y - height/2 == j && x + width/2 == i ||
y + height/2 == j && x + width/2 == i))
regenerateDot(i+1, j, dots);
For something complicated I'd probably break it down into what each condition (grouped by shared &&) is trying to signify and assign it to a sensible variable name.
At most you can remove extra braces, add some spaces and put the logical partitions in different lines as,
if(center == 2 &&
(((y - height/2) == j || (y + height/2) == j) && (x + width/2) == i))
{
regenerateDot(i+1, j, dots);
}
Edit: You have one redundant condition (x + width/2) == i which I have optimized here.
This is the same as the code you posted:
if( center == 2 )
{
if( (x+width/2) == i )
{
if( (y-height/2) == j ) || (y+height/2) == j ) )
{
regenerateDot(i+1, j, dots);
}
}
}
Re-ordering it would give something like :
if (center==2 && (i-x)==(width/2) && abs(j-y)==(height/2))
regenerateDot(i+1, j, dots);
I would do it like this
if (2 == center &&
(((y - height/2) == j && (x + width/2) == i) ||
((y + height/2) == j && (x + width/2) == i))
)
{
regenerateDot(i + 1, j, dots);
}