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 as 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);
}
What you said:
if not (divisible by 3 and divisible by 7) then print
What you wrote:
if not divisible by 3 and not divisible by 7 then print
Not the same thing. Aristotle thought of it first, Augustus De Morgan wrote the laws 158 years ago, apply the not operator to the operands and invert the logical operation:
if not divisible by 3 or not divisible by 7 then print
Which produces:
if (a % 3 != 0 || a % 7 != 0)
Or just write it the way you said it:
if (!(a % 3 == 0 && a % 7 == 0))
Looking at your conditional statement's Truth Table you can see that if
X(NOT multiple of 3) Y(NOT multiple of 7) X && Y
true true 'a' printed as it is not a multiple of either
true false 'a' not printed, it is multiple of 7
false true 'a' not printed, it is multiple of 3
false false 'a' not printed, it is multiple of both
That is why all the multiples of 3 or 7 or 21 are not printed.
What you want: Numbers, that are
not a (multiple of 3 AND 7). And that is
!(a%3==0 && a%7==0) or even further simplified to
!(a%21 == 0) or even
(a%21 != 0)
a % b != 0 means "a is not divisible by b".
If something is not divisible by 3 and not divisible by 7, it's divisible by neither. Thus if it's a multiple of 3 or a multiple of 7, your statement will be false.
It often helps to think of logic in terms of real-world things:
(keep in mind that true and false == false and true or false == true)
The ocean is blue (a is divisible by 3).
The ocean is not yellow (a is not divisible by 7).
What you have:
The ocean is not blue and the ocean is not yellow - this is false (you want this to be true).
What you want:
The ocean is not (blue and yellow) - this is true (the ocean is only blue, not both blue and yellow).
The ocean is not blue or the ocean is not yellow - this is true (the ocean is not yellow).
The equivalent of the last 2 statements would be:
!(a % 3 == 0 && a % 7 == 0)
(a % 3 != 0 || a % 7 != 0)
And you can convert one to the other using De Morgan's laws.
If you don't know how to implement an algorithm, try breaking it down into obviously correct functions that each implement part of the algorithm.
You want to "print all the numbers from 1 to N (user input) except for those that are divisible by 3 and 7 at the same time." Old timers can quickly spit out a correct and efficient implementation using logical operators. As a beginner, you may find it helps to break it down into pieces.
// write out the highest level problem to solve, using functions as
// placeholders for part of the algorithm you don't immediately know
// how to solve
for ($x = 1; $x <= $N; $x++) {
if (is_not_divisible_by_3_and_7($x)) {
print "$x\n";
}
}
// then think about the function placeholders, writing them out using
// (again) function placeholders for things you don't immediately know
// how to do
function is_not_divisible_by_3_and_7($number) {
if (is_divisible_by_3_and_7($number)) {
return false;
} else {
return true;
}
}
// keep repeating this...
function is_divisible_by_3_and_7($number) {
if (is_divisible_by_3($number) && is_divisible_by_7($number)) {
return true;
} else {
return false;
}
}
// until you have the simplest possible functions
function is_divisible_by_3($number) {
if ($number % 3 === 0) {
return true;
} else {
return false;
}
}
function is_divisible_by_7($number) {
if ($number % 7 === 0) {
return true;
} else {
return false;
}
}
This is easier to follow, because each function does one thing and the function name describes exactly that one thing. This also satisfies the first rule of programming: correct code comes first.
You can then start to think of making the code better, where better can mean:
fewer lines of code
less calculations
more comments
Taking this approach with the code above, an obvious improvement is to replace is_divisible_by_3 and is_divisible_by_7 with a generic function:
function is_divisible_by_n($number, $divisor) {
if ($number % $divisor === 0) {
return true;
} else {
return false;
}
}
You can then replace all the big, bulky if x return true else return false with the ternary operator, which gets you to:
function is_divisible_by_n($number, $divisor) {
return ($number % $divisor === 0) ? true : false;
}
function is_divisible_by_3_and_7($number) {
return (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7)) ? true : false;
}
function is_not_divisible_by_3_and_7($number) {
return (is_divisible_by_3_and_7($number)) ? false : true;
}
Now, notice that is_not_divisible_by_3_and_7 looks exactly like is_divisible_by_3_and_7, except the returns are switched, so you can collapse those into one method:
function is_not_divisible_by_3_and_7($number) {
// look how it changed here ----------------------------------------------VVVVV - VVVV
return (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7)) ? false : true;
}
Now, rather than using ternary operators you can leverage the fact that comparisons themselves return a value:
function is_divisible_by_n($number, $divisor) {
// this expression returns a "truthy" value: true or false
// vvvvvvvvvvvvvvvvvvvvvvvvvv
return ($number % $divisor === 0);
}
function is_not_divisible_by_3_and_7($number) {
// also returns a truthy value, but inverted because of the !
// vvv
return ! (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7));
}
Finally, you can just mechanically replace the function calls with their equivalent logical operations:
for ($x = 1; $x <= $N; $x++) {
// all I did below was copy from the function, replace variable names
// v vvvvvvvvvvvvvv vvvvvvvvvvvvvv
if (! (($x % 3 === 0) && ($x % 7 === 0))) {
print "$x\n";
}
}
As bonus points, you can then apply DeMorgan's rule, to distribute the not through the expression:
for ($x = 1; $x <= $N; $x++) {
if ($x % 3 !== 0 || $x % 7 !== 0) {
print "$x\n";
}
}
Additionally, you might observe that two co-prime numbers have common factors if and only if they have common factor N times M, so:
for ($x = 1; $x <= $N; $x++) {
if ($x % (3*7) !== 0) {
print "$x\n";
}
}
You can take this further by using your language's features to compact the expression more:
array_walk(
range(1, $N),
function ($x) {
if ($x % 21 !== 0) print "$x\n";
}
);
And so on. The point is that you start by making your code correct, then you make it better. Sometimes making code correct means thinking long and hard. Sometimes it just means writing it out in very small, very explicit steps.
&& behaves differently to ||
To understand the difference, it may help to do some tests with simpler expressions:
if (true && false)
if (true || false)
So, your problem is with understanding the other operators in your code (!= and %).
It often helps to split conditions into smaller expressions, with explanations:
bool divisbleBy3 = (a % 3 == 0);
bool divisbleBy7 = (a % 7 == 0);
if (divisbleBy3 && divisibleBy7)
{
// do not print
}
else
{
// print
}
Obviously && and || are different.
It states:
if (true && false) = false
if (true || false) = true
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
Recently I have been working on a project that requires a loop to run x amount of times. Simply wanted to exclude certain output x values.
Bellow is an example of what I THOUGH would work:
// Create a 1-58 Loop
for (int n = 1; n < 59; n++)
{
// Exclude Values
if (n != 2 || n != 11 || n != 16 || n != 40)
{
// Display Data
Console.WriteLine(n);
}
}
The operation n != 2 || n != 11 || n != 16 || n != 40 Under any normal situations would exclude the values that do not equal != value x. However this does not work and still renders all values and ignores the operation once a or statement || is introduced.
Bellow is a solution I found after playing around for a bit:
// Create a 1-58 Loop
for (int n = 1; n < 59; n++)
{
// Exclude Values
if (n == 2 ^ n == 11 ^ n != 16 ^ n == 40)
{
// Display Data
Console.WriteLine(n);
}
}
So my question is why does the Logical exclusive || not work in a for loop but a Conditional logical ^ does? I'm pulling my information from this wiki. If i'm wrong about something please have no hesitations to correct me!
if (n != 2 || n != 11 || n != 16 || n != 40)
This will be true on a 2. Because a 2 is not 11.
If you want to exclude those. You should do:
if (n != 2 && n != 11 && n != 16 && n != 40)
^ is the logical exclusive OR, while || is the conditional logical OR. Exclusive OR is different than OR in that exclusive OR requires that one AND ONLY ONE of the conditions evaluates to true, whereas a conditional OR will also return true if both conditions evaluate to true.
Also note that the conditional OR (||) will return as soon as any condition evaluates to true (evaluated from left to right); no other conditions are evaluated since they would have no affect on the outcome (this makes it different than the | operator, where all conditions are evaluated).
Let's take a look at the statement that works:
if (n == 2 ^ n == 11 ^ n != 16 ^ n == 40)
If we break this down for one of the values we want to exclude, say 2 for example, we have:
if (true ^ false ^ true ^ false) =>
\ / / /
\ / / /
if ( true ^ true ^ false ) =>
\ / /
\ / /
if ( false ^ false ) =>
\ /
\ /
if ( false )
Then let's look at the condition that doesn't work and now we see why:
if (n != 2 || n != 11 || n != 16 || n != 40)
For the number 2, this becomes:
if (false || true || true || true)
\ /
\ /
if ( true ) // evaluation stops at the first `true` result
So what else can we do in this situation? Well, we can swap the || operator with the && operator (which is the conditional logical AND operator), which only returns true if both conditions evaluate to true (and it also short circuits if any condition returns false, since no further evaluations are necessary).
Let's take a look:
if (n != 2 && n != 11 && n != 16 && n != 40)
For the number 2, this becomes:
if (false && true && true && true)
\ /
\ /
if ( false ) // evaluation stops at the first `false` result
What is the fastest way to find if a number is even or odd?
It is pretty well known that
static inline int is_odd_A(int x) { return x & 1; }
is more efficient than
static inline int is_odd_B(int x) { return x % 2; }
But with the optimizer on, will is_odd_B be no different from is_odd_A? No — with gcc-4.2 -O2, we get, (in ARM assembly):
_is_odd_A:
and r0, r0, #1
bx lr
_is_odd_B:
mov r3, r0, lsr #31
add r0, r0, r3
and r0, r0, #1
rsb r0, r3, r0
bx lr
We see that is_odd_B takes 3 more instructions than is_odd_A, the main reason is because
((-1) % 2) == -1
((-1) & 1) == 1
However, all the following versions will generate the same code as is_odd_A:
#include <stdbool.h>
static inline bool is_odd_D(int x) { return x % 2; } // note the bool
static inline int is_odd_E(int x) { return x % 2 != 0; } // note the !=
What does this mean? The optimizer is usually sophisticated enough that, for these simple stuff, the clearest code is enough to guarantee best efficiency.
Usual way to do it:
int number = ...;
if(number % 2) { odd }
else { even }
Alternative:
int number = ...;
if(number & 1) { odd }
else { even }
Tested on GCC 3.3.1 and 4.3.2, both have about the same speed (without compiler optimization) as both result in the and instruction (compiled on x86) - I know that using the div instruction for modulo would be much slower, thus I didn't test it at all.
if (x & 1) is true then it's odd, otherwise it's even.
bool is_odd = number & 1;
int i=5;
if ( i%2 == 0 )
{
// Even
} else {
// Odd
}
int is_odd(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return !is_odd(n - 1);
}
Oh wait, you said fastest way, not funniest. My bad ;)
Above function only works for positive numbers of course.
Check to see if the last bit is 1.
int is_odd(int num) {
return num & 1;
}
If it's an integer, probably by just checking the least significant bit. Zero would be counted as even though.
The portable way is to use the modulus operator %:
if (x % 2 == 0) // number is even
If you know that you're only ever going to run on two's complement architectures, you can use a bitwise and:
if (x & 0x01 == 0) // number is even
Using the modulus operator can result in slower code relative to the bitwise and; however, I'd stick with it unless all of the following are true:
You are failing to meet a hard performance requirement;
You are executing x % 2 a lot (say in a tight loop that's being executed thousands of times);
Profiling indicates that usage of the mod operator is the bottleneck;
Profiling also indicates that using the bitwise-and relieves the bottleneck and allows you to meet the performance requirement.
Your question is not completely specified. Regardless, the answer is dependent on your compiler and the architecture of your machine. For example, are you on a machine using one's complement or two's complement signed number representations?
I write my code to be correct first, clear second, concise third and fast last. Therefore, I would code this routine as follows:
/* returns 0 if odd, 1 if even */
/* can use bool in C99 */
int IsEven(int n) {
return n % 2 == 0;
}
This method is correct, it more clearly expresses the intent than testing the LSB, it's concise and, believe it or not, it is blazing fast. If and only if profiling told me that this method were a bottleneck in my application would I consider deviating from it.
Check the least significant bit:
if (number & 0x01) {
// It's odd
} else {
// It's even
}
Can't you just look at the last digit and check if its even or odd if the input is in base 10?
{1, 3, 5, 7, 9} is odd
{0, 2, 4, 6, 8} is even
Additional info: The OP states that a number is a given, so I went with that when constructing this answer. This also requires the number to be in base 10. This answer is mathematically correct by definition of even/odd in base 10. Depending on the use case, you have a mathematically consistent result just by checking the last digit.
Note: If your input is already an int, just check the low bit of that. This answer is only useful for numbers represented as a sequence of digits. You could convert int->string to do this, but that would be much slower than n % 2 == 0.
Checking the last digit does work for a string of digits in any even base, not just 10. For bases lower than 10, like base 8 (octal), 9 and 8 aren't possible digits, but the low digit being odd or even still determines whether the whole number is.
For bases higher than 10, there will be extra possibilities, but you don't want to search a list anyway, just check if the digit as an integer is odd or even using the normal i % 2 == 0 or !=0 check.
For ASCII hex using 'a' .. 'f' to represent digits values 10 through 15, the low bit of ASCII code does not represent odd or even, because 'a' == 0x61 (odd) but represents 10 aka 0xa (even). So you'd have to convert the hex digit to an integer, or do some bit-hack on the ASCII code to flip the low bit according to some other bit or condition.
This question already has answers here:
Mod of negative number is melting my brain
(15 answers)
What is the difference between “int” and “uint” / “long” and “ulong”?
(6 answers)
How to detect a potential overflow
(1 answer)
Closed 3 years ago.
I'm solving some algorithm test which is Collatz conjecture.
In short,
1-1. if the number is even, divide it by 2
1-2. if odd, multiply it by 3 and plus 1
2. repeat the same process 1(1-1 or 1-2), until the number become 1.
For example,
6 become 1, after 8 tries(6 → 3 → 10 → 5 → 16 → 8 → 4 → 2 → 1).
In the test, it should be ended in 500 tries and returns times of try.
If it fails in 500 times, then returns -1.
Here's my code.
using System;
public class Program {
public int Main(int num) {
int answer = -1;
int maxTry = 500;
int count = 0;
if (num == 1)
return count;
for (count = 0; count < maxTry; count++)
{
// 1-1
if (num % 2 == 0)
{
num /= 2;
}
// 1-2
else
{
num = num * 3 + 1;
}
if (num == 1)
{
answer = count + 1;
break;
}
}
Console.Write(answer);
return answer;
}
}
It was working quite well, before meet '626331'!.
In explanation, 626331 can't be 1 in 500 times.
But with my code, it return 488, which means it becomes 1 at 488 tries.
When I printed process repeat by repeat, it looked working well.
After all attempts, found out that dividing was the problem.
I changed this
if (num % 2 == 0)
...
else
...
into
if (num % 2 == 0)
...
else if (num % 2 == 1)
...
Now every case works perfectly!
But I don't have any clue for this situation.
It was online coding test and compile option was C# Mono C# Compiler 5.14.0.177
You're getting overflow, and once overflowed the result will be negative and num % 2 can return 0 or -1. The % operator in C# is the remainder operator, not the mathematical modulo operator. See
Mod of negative number is melting my brain
You need to use a wider integer type (long) and enabling checked mode to detect overflow
how might I find out, in an if statement, weather the specified int is a multiple of 5? This is what I mean:
if(X [is a multiple of] 5)
{
Console.Writeline("Yes");
}
What would be [is a multiple of]?
Also, why is it that when I do:
if(X = 5)
{
Console.Writeline("sdjfdslf");
}
it shows "X = 5" in red and tells me "Can not implicitly convert type "int" to "bool"? I am using X as an input.
how might I find out, in an if statement, weather the specified int is a multiple of 5?
You want to use the modulo operation (%).
if (X % 5 == 0) {
Console.Writeline("Yes");
}
it shows "X = 5" in red and tells me "Can not implicitly convert type "int" to "bool"? I am using X as an input.
The single equals = is assignment. You want the double equals == to do a check for equality.
if (x % 5 == 0) Console.WriteLine("yes");
C# mod operator
Also use == to return a boolean value for a comparison.
You can use the modulus operator (%), which returns the remainder after division:
if (X % 5 == 0) { Console.Writeline("Yes"); }
You're looking for the modulo operator (%) to determine if an integer is a multiple of another integer, like so:
if (x % 5 == 0)
To answer the second part of your question (if (x = 5)), a single equals sign is an assignment operator in C#. You should be using the double equals sign instead, which is the comparison operator, like so: if (x == 5).
= is the assignment operator, while == is used for comparison.
So when your write if (X = 5), you're assigning 5 to X and treat that as a boolean expression.
Interestingly, assigning a value to a variable also returns the value itself.
y = x = 5
assigns 5 to x and assigns the result of (x = 5), which is also 5, to y.
Given a method of the bool data type that takes in an int variable, what is a single line of code that would determine if the int is an exponent of 2 or 2^n.....2,4,8,16,32 etc. I know of a way using a while loop and if statements, but I'm looking for it to be on one line.
From Bit Twiddling Hacks:
uint v; // we want to see if v is a power of 2
bool f; // the result goes here
f = (v != 0) && ((v & (v - 1)) == 0);
Just check if the log (base 2) of the number is an integer.
In one line of C#:
Math.Log(x, 2) % 1 == 0
Bitwise operations are more fun, but lord have mercy on whomever has to maintain that code.
bool powerOfTwo = (unchecked(n & (n-1)) == 0) && (n != 0)
bool answer = ((n & ~(n-1)) == n && n!=0);
This passes all the basic tests I threw at it.
It seems good.