check if all values are even - c

int leavesEven(tree t)
{
if(t == NULL) return 1;
if(t->left == NULL && t->right == NULL)
return t->value % 2 == 0;
return leavesEven(t->left) && leavesEven(t->right);
}
I was given this code as a solution to this task:
For a given tree t, write a function that returns 1 if all values (of the leaves) are even, else return 0.
I dont get this line: return t->value % 2 == 0;
I thought it returns 0 only if value of t modulo 2 equals 0. But this makes no sense, because 0 means that the number was even, so why would I want to return 0, which means that there was an odd number found in the tree??

In C a "true" value is any non-0 value.
The result of comparisons are 0 for false, and 1 for true.
So 2 % 2 == 0 evaluates to 1, since it is true.

Related

Is there a better way to check these two variables instead of four ifs?

There must be two variables for example A and B, these two will either take the values 0 0, 0 1 , 1 0 or 1 1. I need to check these two variables and return a value between 0 to 3, is there a better way to this than doing four if statements like:
if(B == 0 && A == 0){
return 0;
}
if(B == 0 && A == 1){
return 1;
}
if(B == 1 && A == 0){
return 2;
}
if(B ==1 && A == 1){
return 3;
}
The four conditions you have shown could be addressed with the single line:
return A + B * 2;
That is, of course, if the A and B values will never be anything other than 0 or 1.
#AdrianMole has already posted the obvious answer for this particular situation. But a more general solution could look like this:
const int ret[2][2] = {
{ 0, 1, },
{ 2, 3, },
};
return ret[B][A];
Not as clean as in the other answer but much cleaner than a bunch of if statements.

Connect Four Check Winner

So to change my question. It refuses to recognize that there are four twos in a row. It recognizes that there are four ones in a row but that happens after the four twos. Why is this happening?
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 1 1 1 1 0 0
1 2 2 2 2 0 0
int checkFour(int a, int b, int c, int d){
if (a == b == c == d){
return 1;
}
else{
return 0;
}
return 0;
}
//check for the horizontal win
int checkHorizontal(){
for(int i=0; i < rows; i++){
for(int j=0; j < column - 3; j++){
if ((board[i][j] != 0) && (board[i][j+1] != 0) && (board[i][j+2]!= 0) && (board[i][j+3] != 0)){
if (checkFour(board[i][j],board[i][j+1],board[i][j+2],board[i][j+3]) == 1){
printf("Game Over\n");
exit(0);
}
}
}
}
}
What am I doing wrong?
if (a == b == c == d){ does not work the way you might think. The result of a comparison in C is a boolean value of 0 or 1. Given that == operator has left-to-right associativity, your statement can be re-written as:
if ((((a == b) == c) == d)
This appears to give correct results when they are all 1. This is because it ends up comparing the values (1) to the result of the comparison operation, also (1).
(((a == b) == c) == d) a == b -> 1
((1 == c) == d) 1 == c -> 1
(1 == d) 1 == d -> 1
The correct way is to use logical AND.
if (a == b && a == c && a == d)
All three comparisons need to evaluate to true for the entire statement to be true.
Note that there are other combinations that work. Ex:
if (a == b && b == c && c == d)
By the way, you can shorten the entire function to
int checkFour(int a, int b, int c, int d){
return a == b && b == c && c == d;
}
The problem is that you misunderstood the mechanism of C. the code if (a == b == c == d) wouldn't take if abcd are all values equal then return 1. because C computes from left to right(same priority), so it would compute a == b first, the result is 1 or 0, then take this result to compare with c, the second result also is 1 or 0, finally take second result to compare with d and the final result is come out.
The right code is like this:
if ((a == b) && (d == c) && (b == c))
return 1;
else
return 0;

Regarding if else statements in C language

Please explain to me why this code is wrong for the task and below I have explained all the four conditions -[][1]
#include stdio.h
int main()
{
int n;
scanf ("%d", &n); //taking input
if (n / 2 != 0)
{
printf ("Weird"); //checking first condition
}
else if (n % 2 == 0 && 2 <= n <= 5)
{ //checking second condition
printf ("Not Weird");
}
else if (n % 2 == 0 && 6 <= n <= 20)
{ //checking third condition
printf ("Weird");
}
else if (n % 2 == 0 && n > 20)
{ //checking fourth condition
printf ("Not Weird");
}
else
{
printf ("Error");
}
return 0;
}
this is the image for the question[1]: https://i.stack.imgur.com/OtY7o.png**
Testing for Odd or Even
n / 2 != 0 does not test whether n is odd. n/2 calculates the quotient that results from dividing n by 2 (rounding any fraction down). So 0/2 is 0, 1/2 is 0, 2/2 is 1, 3/2 is 1, 4/2 is 2, and so on. So n / 2 != 0 is true for all n other than −1, 0, and 1.
To test whether a number is odd, you can use n % 2 != 0. n%2 calculates the remainder from the division. If it is zero, n is even. If n is not zero, n is odd.
Using Else Efficiently
Once you have tested whether n is odd using n % 2 != 0, you do not have to test whether it is even in the else clauses. The else expressions and their statements will be evaluated only if the if expression is false, which happens (after the correction above) only when n is even. So we do not need to test again.
Testing For an Interval
In C, 2 <= n <= 5 does not test whether n is between 2 and 5. It is parsed as (2 <= n) <= 5. This is evaluated by comparing 2 to n, which produces 0 (if false) or 1 (if true). This result, 0 or 1, is then used in … <= 5. Since 0 and 1 are both less than or equal to 5, the result is always 1 (for true).
To test whether n is greater than or equal to 2 and less than or equal to 5, you must write this out explicitly: 2 <= n and n <= 5, which we join with the “and” operator, &&: 2 <= n && n <= 5.
Other Issues
The proper form for including stdio.h is #include <stdio.h>, not #include stdio.h.
A proper declaration for main is int main(void), not int main().
Corrected Program
A program with these issues corrected is:
#include <stdio.h>
int main(void)
{
int n;
scanf("%d", &n); //taking input
if (n % 2 != 0)
{
printf ("Weird"); //checking first condition
}
else if (2 <= n && n <= 5)
{ //checking second condition
printf ("Not Weird");
}
else if (6 <= n && n <= 20)
{ //checking third condition
printf ("Weird");
}
else if (n > 20)
{ //checking fourth condition
printf ("Not Weird");
}
else
{
printf ("Error");
}
return 0;
}
There is a typo in the line:
if (n / 2 != 0)
The compiler will not complain, but you will get unexpected results at run time.
Here you meant to check if the remainder of division by 2 is not equal to zero (i.e.: modulus operator), and not the division by 2. This line should be
if (n % 2 != 0)
Second thing: you can't tell C to compare values in ranges like this 2 >= n >= 4. You will have to split the comparison into 2 comparisons. This line:
else if (n % 2 == 0 && 2 <= n <= 5)
Should be:
else if (n % 2 == 0 && 2 <= n && n <= 5)
You will need to fix all the lines that have this comparison as well.

Testing if a number goes evenly into 6? [duplicate]

This question already has answers here:
modulo operation on negative numbers [duplicate]
(2 answers)
Closed 5 years ago.
I am trying to see if two input numbers (integers) including negative numbers go into 6 evenly (remainder is 0). This is the code I was trying.
if((in1)%6 == 0 && (in2)%6 == 0){
printf("Divisible: both\n");
}
else if((in1)%6 == 0 && (in2)%6 > 0){
printf("Divisible: only %i\n",in1);
}
else if((in1)%6 > 0 && (in2)%6 == 0){
printf("Divisible: only %i\n",in2);
}
else{
printf("Divisible: neither\n");}
This works for all positive integer but for any negatives the printed code is always "Divisible: neither" any help as to how I can show both positive and negative numbers divisible by six with a remainder of 0 would be really helpful
You could use != 0 instead of > 0. In C, % of negative number will give a negative result (or zero).
This is because a / b is defined as truncation-towards-zero since C99 (in C90 it was implementation-defined). And a % b is defined as a - (a / b) * b.
Note that you actually do not need this test at all; you can rely on the behaviour of if...else not entering the else case if the if case was satisfied, e.g.:
if ( in1 % 6 == 0 && in2 % 6 == 0 )
{
// ...
}
else if ( in1 % 6 == 0 )
{
// would not reach here if in2 % 6 == 0
}
else if ( in2 % 6 == 0 )
{
// would not reach here if in1 % 6 == 0
}
else
Another consideration, rather than oblige code to test numbers 3 times, re-write to perform only 2 test on the numnbers.
if (in1 % 6) {
if (in2 % 6) {
printf("Divisible: both\n");
} else {
printf("Divisible: only %i\n",in1);
}
} else {
if (in2 % 6) {
printf("Divisible: only %i\n",in2);
} else {
printf("Divisible: neither\n");}
}
}

Loop with 2 conditions is exiting when 1 condition is met

I want the loop to exit when both strncmp() and check() return 0, meaning they both found a match. The problem is, when check() returns 0 and strncmp() does not return 0 the loop is exiting.
while (strncmp(buf, match, 3) != 0 && check(buf[3]) != 0)
{
}
I have checked the values in buf and match and they do not match when it exits. buf[3] does match when it exits.
You are using && so you're saying both strncmp(buf, match, 3) and check(buf[3]) != 0 must be met in order for the loop to continue. To get the result you specified you should use ||
This loop runs as long as
buf and match differ somewhere in the first 3 characters, AND
check(buf[3]) is nonzero
Is that what you want? In other words, the loop exits when either
buf and match share the same three initial characters OR
check(buf[3]) is zero
I want the loop to exit when both strncmp() and check() return 0
Then you can rewrite the loop to be very easy to verify against your requirement:
for(;;) {
...
if (strncmp(buf, match, 3) == 0 && check(buf[3]) == 0)
break;
...
}
Now place the negated condition in the controlling expression of the loop:
while (! (strncmp(buf, match, 3) == 0 && check(buf[3]) == 0) ) {
...
}
If you are somewhat into computer science, you realize that not(A and B) is--per de Morgan's Laws--equivalent to (not A) or (not B). This finally yields:
while (strncmp(buf, match, 3) != 0 || check(buf[3]) != 0) {
}
So your error was using && instead of || for the logical operator.
u can try this ...
int c,d;
while ((c=strncmp(buf, match, 3) != 0) && (d=check(buf[3]) != 0))
{}
Description:
strncmp() will return a value that have to store in a var..if u don't do then how it will compare with 0..same as also check().

Resources