I am a beginner and I've been trying to run a program that prints all the numbers from 1 to N (user input) except for those that are divisible by 3 and 7 at the same time. What my code does instead, however, is that it prints the numbers from 1 to N except for those that are divisible by 3 or 7. I examined it for a while and I have no idea why it does that. Please explain to me where I'm going wrong.
static void Main(string[] args)
{
int n = 0;
int a = 0;
n = Convert.ToInt32(Console.ReadLine());
while (a <= n)
{
a++;
if (a % 3 != 0 && a % 7 != 0)
{
Console.WriteLine(a);
}
}
Console.ReadKey();
}
When I reverse the signs of the if statement to ==
the &&
operator works properly, but if the sign is !=
it simply acts like an ||
operator, so that confuses me even more. The issue is most likely in the condition, but I can't see what is wrong with it.
"Except numbers that are divisible by 3 and 7 at the same time" can be broken down as follows:
"divisible by 3 and 7 at the same time"
can be expressed as:
"(divisible by 3 and divisible by 7)"
"Except"
can be expressed as "Not"
.
So you get:
Not (divisible by 3 and divisible by 7)
"divisible by 3" is (a % 3) == 0
"divisible by 7" is (a % 7) == 0
Giving:
Not ( (a % 3) == 0 and (a % 7) == 0)
In C# Not
becomes !
and and
becomes &&
, so you can write the whole thing in C# as:
if (!((a % 3) == 0 && (a % 7) == 0))
Compare with your incorrect:
if (a % 3 != 0 && a % 7 != 0)
This latter is incorrect because it means:
if (the number is not divisible by 3) and (the number is not divisible by 7
).
i.e. it means "Print the number if it is neither divisible by 3 nor divisible by 7"
, which means "don't print the number if it's divisible by 3 or 7"
.
To see why, first consider the number 6:
6 is not divisible by 3? = false (because 6 *is* divisible by 3)
6 is not divisible by 7? = true (because 6 is *not* divisible by 7)
So this resolves to if false and true
which is, of course, false
.
This result also applies to any other number divisible by 3, so no numbers divisible by 3 will be printed.
Now consider the number 14:
14 is not divisible by 3? = true (because 14 is *not* divisible by 3)
14 is not divisible by 7? = false (because 14 *is* divisible by 7)
So this resolves to if true and false
which is, of course, false
.
This result also applies to any other number divisible by 7, so no numbers divisible by 7 will be printed.
Hopefully you can see why it's wrong now. If not, consider this equivalent example:
Suppose we have four people, Tom the Carpenter, Dick the Carpenter, Harry the Butcher and Tom the Butcher.
This question is equivalent to the one you're asking:
Name every person who is (not called Tom and is not a Butcher)
And you should be able to see that this the same as asking:
Name every person except (anyone called Tom or anyone who is a Butcher)
In both cases, the answer is Dick the Carpenter.
The question you should have asked is:
Name every person except (anyone called Tom who is also a butcher)
To which the answer is Tom the Carpenter, Dick the Carpenter and Harry the Butcher.
Footnote: De Morgan's laws
The second law states that:
"not (A or B)" is the same as "(not A) and (not B)"
This is the equivalent of my example above where:
Name every person except (anyone called Tom or anyone who is a Butcher)
is the equivalent to:
Name every person who is (not called Tom and is not a Butcher)
where A is anyone called Tom
and B is anyone who is a butcher
and not
is written as except
.
You should read De Morgan's laws
"not (A and B)" is the same as "(not A) or (not B)"
also,
"not (A or B)" is the same as "(not A) and (not B)".
a % 3 != 0 && a % 7 != 0
is true when a
is not divisible by 3 (a % 3 != 0
) and not divisible by 7 (a % 7 != 0
). So all a
s which are divisible by 3 or 7 (3,6,7,9,12,14,...)
makes the whole expression false. You can rephrase it like !(a % 3 == 0 || a % 7 == 0)
All you really need is:
if ((a%21) != 0) Console.WriteLine(a);
Explanation: The numbers that are divisible by both a and b are essentially the numbers divisible by the LCM of a and b. Since, 3 and 7 are prime number, you are basically looking for numbers that are not divisible by 3*7.
Should be:
if ( !(a % 3 == 0 && a % 7 == 0) )
{
Console.WriteLine(a);
}
It means exactly: all the numbers except for those that are divisible by 3 and 7 at the same time.
You could also rephrase it as:
if ( a % 3 != 0 || a % 7 != 0 )
{
Console.WriteLine(a);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With