How to write a simplified if condition - if-statement

I have three parameters value1, value2, value3 and I am supposed to check for four different values in them. Is there a simplified way to write the equivalent condition in Java or in JavaScript :
if ((value1 == 11) || (value1 == 88) || (value1 == 66) || (value1 == 33) ||
(value2 == 11) || (value2 == 88) || (value2 == 66) || (value2 == 33) ||
(value3 == 11) || (value3 == 88) || (value3 == 66) || (value3 == 33)) {

here is 3 different versions of the function which validates given condition:
static final int[] SORTED_VALUES = new int[] {11, 33, 66, 88};
static boolean isAtLeastOneEquals1(final int value1, final int value2, final int value3) {
for (final int i : SORTED_VALUES)
if ((i == value1) || (i == value2) || (i == value3))
return true;
return false;
}
static boolean isAtLeastOneEquals2(final int value1, final int value2, final int value3) {
return (Arrays.binarySearch(SORTED_VALUES, value1) >= 0)
|| (Arrays.binarySearch(SORTED_VALUES, value2) >= 0)
|| (Arrays.binarySearch(SORTED_VALUES, value3) >= 0);
}
static boolean isAtLeastOneEquals3(final int... values) {
for (final int v : values)
if (Arrays.binarySearch(SORTED_VALUES, v) >= 0)
return true;
return false;
}
personally I prefer 2nd one, but 3rd is more universal

Related

how to get rid of warning: control reaches end of non-void function c++

I wrote this code and don't understand why there´s a warning, as far as I can tell every branch has a return value. How could I fix this?
bool ValidDate(int d, int m, int a) {
if ((m < 1) || (m > 12)) {
return false;
} else {
if ((m == 1) || (m == 3) || (m == 5) || (m == 7) || (m == 8) || (m == 10) || (m == 12)) {
if (d >= 1 && d <= 31) {
return true;
} else {
return false;
}
} else if ((m == 4) || (m == 6) || (m == 9) || (m == 11)) {
if (d >= 1 && d <= 30) {
return true;
} else {
return false;
}
} else if (m == 2) {
if (a % 4 == 0) {
if (d >= 1 && d <= 29) {
return true;
} else {
return false;
}
} else {
if (d >= 1 && d <= 28) {
return true;
} else {
return false;
}
}
}
}
}
I undestand what the error means but can´t find where the problem is.
The warning arises because the compiler does not know that the else if (m == 2) condition will always be true when that condition is checked, as all other possibilities must have been exhausted. Since the compiler does not perform this kind of analysis, you as the programmer might as well help the compiler by explicitly saying so by just removing that check. You can still leave in a comment saying "m must be 2" to help human readers of the code.
The nested if-else branches can also be simplified considerably by noting the following equivalent constructs:
A check like
if (expr)
return true;
else
return false;
can always be replaced by
return expr;
Similarly, if you're returning at the end of a branch, the subsequent else is redundant. i.e.
if (expr1) {
// ...
return // ...;
}
else if (expr2) {
// ...
return // ...;
}
can be replaced by
if (expr1) {
// ...
return // ...;
}
if (expr2) { // the else is redundant here
// ...
return // ...;
}
Applying these transformations give a cleaner function:
bool ValidDate2(int d, int m, int a) {
if ((m < 1) || (m > 12))
return false;
if ((m == 1) || (m == 3) || (m == 5) || (m == 7) || (m == 8) || (m == 10) || (m == 12))
return d >= 1 && d <= 31;
if ((m == 4) || (m == 6) || (m == 9) || (m == 11))
return d >= 1 && d <= 30;
// Now m must be 2
return a % 4 == 0 ?
d >= 1 && d <= 29 :
d >= 1 && d <= 28;
}
Note that I've replaced the last if-else by a ternary operator ?:, though whether this makes the code more readable is subjective. Certainly nesting multiple ?: can make it harder to see the structure of the branches.
Here's a demo.
Another way of restructuring the code is to use a switch statement for all the different values of m. This reduces the complexity of the if conditionals, and can make the code easier to read:
bool ValidDate2(int d, int m, int a) {
switch(m) {
case 1: [[fallthrough]];
case 3: [[fallthrough]];
case 5: [[fallthrough]];
case 7: [[fallthrough]];
case 8: [[fallthrough]];
case 10: [[fallthrough]];
case 12: return d >= 1 && d <= 31;
case 4: [[fallthrough]];
case 6: [[fallthrough]];
case 9: [[fallthrough]];
case 11: return d >= 1 && d <= 30;
case 2: return a % 4 == 0 ?
d >= 1 && d <= 29 :
d >= 1 && d <= 28;
default: return false; // m < 1 or m > 12
}
}
Here's a demo.

C++ boolean arrays conditional long statement

So, I can't search what the meaning of this let say for example I have
string TICTACTOE[3][3] = {
{"1","2","3"},
{"4","5","6"},
{"7","8","9"}
};
How can I make boolean passing the condition statement in something like this
bool trial = TICTACTOE[0][0] == TICTACTOE[0][1] == TICTACTOE[0][2]
if (trial) {
cout << "THIS PLAYER WINS: " <<playerWinner << endl;
}
Its working though if its only
bool trial = TICTACTOE[0][0] == TICTACTOE[0][1]
but when its three bool its not working..anyone can explain me this?
I'm just used to do with it "==" since I used to use javascript a lot.
You can do this
int check()
{
if (a[1] == a[2] && a[2] == a[3]) return 1; //GAME IS OVER WITH RESULT
else if (a[4] == a[5] && a[5] == a[6]) return 1;
else if (a[7] == a[8] && a[8] == a[9]) return 1;
else if (a[1] == a[4] && a[4] == a[7]) return 1;
else if (a[2] == a[5] && a[5] == a[8]) return 1;
else if (a[3] == a[6] && a[6] == a[9]) return 1;
else if (a[1] == a[5] && a[5] == a[9]) return 1;
else if (a[3] == a[5] && a[5] == a[7]) return 1;
if ( a[1] != '1' && a[2] != '2' && a[3] != '3' && a[4] != '4' &&
a[5] != '5' && a[6] != '6' && a[7] != '7' && a[8] != '8' && a[9] != '9')
return 0; //GAME IS OVER AND NO RESULT
else
return -1; //GAME IS IN PROGRESS
}

Verifying that inputs are in range

I'm having a problem implementing this.. the program is meant to take date input in the format dd.mm.yyyy, it does that already but I've been trying to add the code that checks
if the date is more than 31 or February is more than 28
if the month is more than 12
It should return an error since the input is incorrect
And also if a user start input with . then the program shouldn't allow more than 2 inputs of .. so that the user can just just go back with the arrow buttons and type in the correct input
#include "examplevalidator.h"
ExampleValidator::ExampleValidator(QObject* parent)
: QValidator (parent)
{
}
ExampleValidator::~ExampleValidator()
{
}
QValidator::State ExampleValidator::validate( QString & input, int & pos ) const
{
if (input.isEmpty()) return Intermediate;
bool ok;
QString str;
str = input[pos-1];
if(input.size() == 10
&& ((input[2] == '.'))
&& ((input[5] == '.'))
&& input[0].isDigit()
&& input[1].isDigit() && (input.toInt(&ok, 10) <= 31)
&& input[3].isDigit()
&& input[4].isDigit() && (input.toInt(&ok, 10) <= 12)
&& input[6].isDigit()
&& input[7].isDigit()
&& input[8].isDigit()
&& input[9].isDigit() && (input.toInt(&ok, 10) <= 2020)
// && (pos == 1 )&& (input.toInt(&ok, 10) <= 3)
// && (pos == 2 )&& (input.toInt(&ok, 10) <= 31)
)
return Acceptable;
if(input.size() > 10)
return Invalid;
if((pos == 1 )&& (input.toInt(&ok, 10) <= 3) && input[0].isDigit())
{return Intermediate;}
if((pos == 2) && (input.toInt(&ok, 10) <= 31) && input[pos-1].isDigit())
{return Intermediate;}
if((pos == 3) && (input.toInt(&ok, 10) <= 1) && input[pos-1].isDigit())
{return Intermediate;}
if((pos == 4) && (input.toInt(&ok, 10) <= 1) && input[3].isDigit())
{return Intermediate;}
if((pos == 5) && (input.toInt(&ok, 10) <= 12) && input[4].isDigit())
{return Intermediate;}
// if((pos == 6) && (input.toInt(&ok, 10) <= 999999) && input[pos-1].isDigit())
// {return Intermediate;}
if((pos == 7) && (input.toInt(&ok, 10) <= 9) && input[6].isDigit())
{return Intermediate;}
if((pos == 8) && (input.toInt(&ok, 10) <= 99) && input[7].isDigit())
{return Intermediate;}
if((pos == 9) && (input.toInt(&ok, 10) <= 999) && input[8].isDigit())
{return Intermediate;}
if((pos == 10) && (input.toInt(&ok, 10) < 99999) && input[9].isDigit())
{return Intermediate;}
if (input[0] == '.' )
{return Intermediate;}
if(pos > 1)
{
if (input.isEmpty()) return Intermediate;
if((pos > 1) || (pos <=2 ) && (input[pos-1] == '.'))
return Intermediate;
if(pos > 8 && pos <= 10 && input[pos-1].isDigit())
{return Intermediate;}
else {return Invalid;}
}
}
You can use a regular expression to validate dd.mm.yyyy
Have a look at https://regex101.com/ for trying them out.
Something like the code below should get you started
#include <regex>
std::smatch match;
const std::regex ddmmyyyyRegExp(R"((([0-9]{2})\.([0-9]{2})\.([0-9]{4})))");
std::string dd;
std::string mm;
std::string yyyy;
if (std::regex_search(input, match, ddmmyyyyRegExp) && match.size() == 4)
{
dd= match.str(1);
mm= match.str(2);
yyyy= match.str(3);
}
I've been able to fix the code, but still I'm unable to check if the inputs are in a particular range. I'm trying to check if the date limit isn't more than 31 and month isn't greater than 12
ExampleValidator::ExampleValidator(QObject* parent)
: QValidator (parent)
{
}
ExampleValidator::~ExampleValidator()
{
}
QValidator::State ExampleValidator::validate( QString & input, int & pos ) const
{
if (input.isEmpty()) return Intermediate;
bool ok;
QString str;
str = input[pos-1];
if(pos > 0 && input[0] != '.')
{
if (input.isEmpty()) return Intermediate;
if(((pos == 1 )&& (input.toInt(&ok, 10) <= 9) && input[0].isDigit() && input.size() != 10))
{return Intermediate;}
if(((pos == 2) && (input.toInt(&ok, 10) <= 99) && input[1].isDigit() && input.size() != 10))
{return Intermediate;}
if(((pos == 3) && (input.toInt(&ok, 10) <= 999)) && (input[2].isDigit() || input[2] == '.') && input.size() != 10)
{return Intermediate;}
if((pos == 4) && (input.toInt(&ok, 10) <= 9999) && input[3].isDigit() && input.size() != 10)
{return Intermediate;}
if((pos == 5) && (input.toInt(&ok, 10) <= 99999) && input[4].isDigit() && input.size() != 10)
{return Intermediate;}
if(((pos == 6) && (input.toInt(&ok, 10) <= 999999)) && (input[5].isDigit() || input[5] == '.') && input.size() != 10)
{return Intermediate;}
if((pos == 7) && (input.toInt(&ok, 10) <= 99999999) && input[6].isDigit() && input.size() != 10)
{return Intermediate;}
if((pos == 8) && (input.toInt(&ok, 10) <= 999999999) && input[7].isDigit() && input.size() != 10)
{return Intermediate;}
if((pos == 9) && (input.toInt(&ok, 10) <= 999999999) && input[8].isDigit() && input.size() != 10)
{return Intermediate;}
if((pos == 10) && (input.toInt(&ok, 10) < 2020) && input[9].isDigit() && input[2] == '.' && input[5]=='.' )
{
return Acceptable;}
}
if(((pos == 1) && (input[0] == '.')) || ((pos == 2) && (input[1] == '.')))
{
return Intermediate;
}
else if (input.isEmpty()) {return Intermediate;}
}```

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

Why doesn't this output "Please try again" when loop runs again?

Hello I am trying to learn c++ and I wanted to give a little practice with a program. However I'm having trouble using cout within the loop.
This is the loop I'm trying to output text from. When the user enters a number that isn't valid it is supposed to say "Sorry try again!"
while (datecheck)
{
bool check(false);
if (check)
std::cout<<"Sorry try again!"<<std::endl;
std::cin>>c;
if (c >= 1)
{
if (b == 2 && c <= 28)
datecheck = false;
if (b == 2 && a % 4 == 0 && c <= 29)
datecheck = false;
if (b == 4 || b == 6 || b == 9 || b == 11 && c <= 30)
datecheck = false;
if (c <= 31)
datecheck = false;
}
check = true;
}
When it outputs and I purposely keep myself in the loop it doesn't output anything
Year: -20
-20
-20
You declare a fresh new variable check at every iteration. And you initialize that variable to false every time. So move that declaration before the while loop.
Change this:
while (datecheck)
{
bool check(false);
...
check = true;
}
to this:
bool check(false);
while (datecheck)
{
...
check = true;
}
The problem is with declaration of bool check(false);. This keeps on re-assigning value to false at beginning of each iteration.
A simple fix could be to get-rid of use of check variable and use only datecheck.
bool datecheck(true);
while (true)
{
std::cin>>c;
if (c >= 1)
{
if (b == 2 && c <= 28)
datecheck = false;
if (b == 2 && a % 4 == 0 && c <= 29)
datecheck = false;
if (b == 4 || b == 6 || b == 9 || b == 11 && c <= 30)
datecheck = false;
if (c <= 31)
datecheck = false;
}
if (datecheck)
{
std::cout<<"Sorry try again!"<<std::endl;
}
else
{
break;
}
}