First question, I'm trying to do a practice where I am asked to return true if the given non-negative number is a multiple of 3 or 5, but not both. Examples are;
old35(3) → true
old35(10) → true
old35(15) → false
So 3 would be true, as it's a multiple of 3, but I can't currently make my code work for all instances. Code below;
public boolean old35(int n) {
if ((35 % n == 3) || (35 % n == 5))
return true;
return false;
}
How could I edit this to fit the criteria of what the practice is telling me to do?
>
I will throw a detailed explanation. First, you use the remainder sign to check the condition where remainder is zero;
n % 3 == 0
and
n % 5 == 0
Then for a one to one translation for your conditions, put them together as:
((n % 3 == 0) || (n % 5 == 0)) // Multiple of 3 or 5
!((n % 3 == 0) && (n % 5 == 0)) // But not both
Add (and) them together;
public static boolean old35(int n) {
return(((n % 3 == 0) || (n % 5 == 0)) && !((n % 3 == 0) && (n % 5 == 0)));
}
But simply, what you are doing is the XOR (^) operation, the following code is valid and simple:
public static boolean old35(int n) {
return((n % 3 == 0) ^ (n % 5 == 0));
}
You can use the logical XOR of the conditions. Basically you can do C1 ^ C2.
Edit: To check if multiple of 3 you must check n % 3 == 0, the same for multiple of 5.
Related
Currently I am working on a little personal project to help myself learn about coding.
I'm wondering for future reference if I can combine logical operators of different types in a single if statement.
For example if I had
if (n == 0 || n == 1 && m == 0 || m == 1) {
doSomething();
}
Would it check if either parts of the left side are true, then if either parts of the right are true, or would it do something similar to checking if both of the middle ones are true?
Does using parenthesis change anything
For example
if ((n == 0 || n == 1) && (m == 0 || m == 1)) {
doSomething();
}
Edit:
From a suggestion I tried it out, but when i put three variables it started acting weird
Here's my test:
int n = 1;
int m = 1;
int o = 1;
if (n == 0 || n == 1 && m == 0 || m == 1 && o == 0 || o == 1) {
System.out.println("True");
}
else {
System.out.println("False");
}
if ((n == 0 || n == 1) && (m == 0 || m == 1) && (o == 0 || o == 1)) {
System.out.println("True");
}
else {
System.out.println("False");
}
if all of them are 1 or 0, they both evaluate true, if n or m is not 1 or 0 the top evaluates true but the bottom does not.
However if o is not 0 or 1 both of them are false.
I have found that parenthesis do in fact make a difference, but I can't quite tell why it's acting the way it is.
&& has a higher precedence then ||, so n == 0 || n == 1 && m == 0 || m == 1 equals n == 0 || (n == 1 && m == 0) || m == 1. You may check the precedence table here.
I'm doing a hackernet challenge where n is an int input. The conditions are:
If n is odd, print Weird
If n is even and in the inclusive range of 2 to 5, print Not Weird
If n is even and in the inclusive range of 6 to 20, print Weird
If n is even and greater than 20, print Not Weird.
Im sure the code makes logic and dont think theres syntax. It gives the correct responses and hackernet still says its incorrect so ive come here to see if anyone can see what the problem is
public static void main(String[] args)
{
int N = scanner.nextInt();
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
if (N % 2 != 0 || N % 2 == 0 && N >= 6 && N <= 20)
{
System.out.print("weird");
}
else
{
System.out.print("not weird");
}
}
The problem is the logic in your else condition, which would also catch values of N which are less than 2. Try this version:
if (N % 2 != 0)
{
System.out.print("weird");
}
else if (N >= 2 && N <= 5 || N > 20)
{
System.out.print("not weird");
}
else if (N >= 6 && N <= 20)
{
System.out.print("weird");
}
else
{
// NOTE: if the code still fails, remove this else condition
System.out.print("unexpected value of N");
}
Note: To get your code to pass the Hackernet task, you might have to completely remove the else condition. I added it for completeness, but Hackernet might test N=1 to see if nothing gets printed.
Read this condition :
if (N % 2 != 0 || N % 2 == 0 && N >= 6 && N <= 20)
as
if (N % 2 != 0 || (N % 2 == 0 && N >= 6 && N <= 20))
Then see how operator precedence changes the behaviour and yield desired results.
Check the following one
public static void main(String[] args)
{
int N = scanner.nextInt();
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
if(N%2!=0) {
System.out.print("weird");
}else if(N>=2 && N<=5) {
System.out.print("not weird");
}else if(N>=6 && N<=20) {
System.out.print("weird");
}else if(N>20) {
System.out.print("not weird");
}
}
For the technical part: start by reading about
precedence of java operators and then make your code easier to read.
Pushing that many conditions into a single if is not helpful. You see it yourself: you think the code is correct, but probably it isn't. And now you look to other people to explain your overly complex code back to you. And of course, all the other answers do all that for you ... but beyond that:
The "real" answer here is: learn how to test your code.
Instead of having a main that somehow asks for a number, and then makes decisions, write a method boolean isWeird() that takes a number and returns true/false according to your requirements.
And then simply test that method with all reasonable cases. And then check if that result is as expected.
Using JUnit, you could write something like
assertThat(isWeird(1), true);
assertThat(isWeird(21), true);
assertThat(isWeird(22), true);
...
Ideally, you write such tests before you implement that method. And then you implement all the conditions, and any check that fails tells you that you got something wrong.
I feel, In the if (N % 2 != 0 || N % 2 == 0 && N >= 6 && N <= 20) condition, you are verifiying the odd and even values at same time using && and || operator. Can you modify the condition into like this if (N % 2 != 0 || (N % 2 == 0 && N >= 6 && N <= 20)) and check? If N is odd weird will be printed or if N is even and it falls under the 6 and 20 inclusive, weird will be printed.
You already have a good few answers here but if you think logically about what you actually need, you can break it down easier.
It looks like the only "Not Weird" print out is 2, 4 and even numbers > 20
So an example could be something like:
if (n % 2 == 0) {
if ((n >= 2 && n <= 5) || (n > 20)) {
return "Not Weird";
}
}
return "Weird";
You can try this
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
int n = scanner.nextInt();
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
if (n % 2 == 1 || (n >= 6 && n <= 20)) {
System.out.println("Weird");
} else {
System.out.println("Not Weird");
}
scanner.close();
}
I'm new to programming
if( (N%2==0) && (6<=N<=20) )
Throws the error below
The operator <= is undefined for the argument type(s) boolean, int
Please help me fix it.
You can't compound the statement like that. You need to && it.
For example,
if ((N % 2 == 0) && (6 <= N && N <= 20)) {...}
The reason you get the error is the first condition of 6 <= N resolves to a boolean and you then attempt to check if a boolean is <= to an int. That does not compute.
You can't compare 2 conditions in one check, you need to split it to two checks
if (N % 2 == 0 && N >= 6 && N <= 20)
You should separate the conditions with logical operators (&& in this case):
if (N % 2 == 0 && N>=6 && N <= 20)
I have an algorithm to test for primality, which uses the naive implementation as listed here http://en.wikipedia.org/wiki/Primality_test#Naive_methods
static boolean check(int n)
{
if(n == 2 || n == 3)
{
return true;
}
if(n < 2 || n % 2 == 0 || n % 3 == 0)
{
return false;
}
for(int i = 6; i * i <= n; i += 6)
{
if(n % (i - 1) == 0 || n % (i + 1) == 0)
{
return false;
}
}
return true;
}
I got all the way to the 6k+1 section, but after that, I'm lost. How else can I further optimize this for speed?
If you want to stick with the naive method, then your next step is to use the next property listed in the wikipedia page you link to:
So all prime numbers are of the form 30k + i for i = 1, 7, 11, 13, 17,
19, 23, 29 (i.e. for i < 30 such that gcd(i,30) = 1).
Except you might pick slightly different / more primes than 2.3.5
You would replace the 6 stepping loop with a 30 stepping loop, (and check with all primes less than 30 by hand )
The code might look like this:
static boolean check(int n)
{
if(n<30)
{
return n==2 || n==3 || n==5 || n==7 || ...
}
for(int i = 30; i * i <= n; i += 30)
{
if (n % (i + 1))==0 return false;
if (n % (i + 7))==0 return false;
if (n % (i + 11))==0 return false;
if (n % (i + 13))==0 return false;
if (n % (i + 17))==0 return false;
if (n % (i + 19))==0 return false;
if (n % (i + 23))==0 return false;
if (n % (i + 29))==0 return false;
}
return true;
}
However you'll note that this scans 8/30 (=27%) numbers, while the 6 stepping loop scans 2/6
(=33%) So it scans about 20% less numbers, so you'd expect a speed up of at best 20%. As you add more primes to the list you get diminishing returns.
Really if you need fast prime checking then you need to move away from the naive methods. And there's been plenty of questions about those on stack overflow previously.
Here's the sample code:
public static void col (int n)
{
if (n % 2 == 0)
n = n/2 ;
if (n % 2 != 0)
n = ((n*3)+1) ;
System.out.println (n) ;
if (n != 1)
col (n) ;
}
this works just fine until it gets down to 2. then it outputs 2 4 2 4 2 4 2 4 2 4 infinitely. it seems to me that if 2 is entered as n then (n % 2 == 0) is true 2 will be divided by 2 to yeild 1. then 1 will be printed and since (n != 1) is false the loop will terminate.
Why doesn't this happen?
Because when you get to 1, you are multiplying by 3 and adding 1, taking you back to 4.
You need an ELSE in there. I don't know java, but it would look something like:
public static void col (int n)
{
if (n % 2 == 0)
n = n/2 ;
else if (n % 2 != 0)
n = ((n*3)+1) ;
System.out.println (n) ;
if (n != 1)
col (n) ;
}
EDIT: as mentioned in the comments, you can omit the if test after the else:
if (n % 2 == 0)
n = n/2 ;
else
n = ((n*3)+1) ;
I think you'll have to change the 2nd if statement to an else
if (n % 2 == 0) // if the n is even
n = n/2 ;
else // if n is odd
n = ((n*3)+1) ;
The answer to the question can be read directly in the code:
Assume n is 2
(n % 2 == 0) is true therefore n <- 1
(n % 2 != 0) is also true therefore 4 <- n
this warrants a call to function with n = 4, which is then changed to 2 and
"back to square 1"
by replacing the second test by an else, you solve this logic problem, at the cost of possibly causing more recursion (since in the current logic, two operations are sometimes performed in one iteration). Such a fix will also solve a more subtle bug, which is that in the current version not all new values of n are printed out.
Now, for extra credit, prove that not matter the initial value of n, the number of recursions is finite (i.e. the sequence converges to 1). ;-)
Use if/then/else. Your logic is wrong.
when the input is 2:
if (n % 2 == 0) //true
n = n/2; //n = 1
if (n % 2 != 0) //true
n = ((n*3)+1); //n = 4
System.out.println (n); //prints 4
if (n != 1) //true
col (n); //call col(4)
Does it work if you change it to this?
if (n % 2 == 0)
n = n/2 ;
else if (n % 2 != 0)
n = ((n*3)+1) ;
It looks like you're getting 2, dividing by 2 to get 1, then checking to see if 1/2 has a remainder (it does), and multiplying it by 3 and adding 1, to get 4....
if (n % 2 != 0)
n = ((n*3)+1) ;
this code is again implemented whenever u get 1.
therefore the recursive function will be called repeatedly hence leading to an infinite rec calling and code will never terminate.
in addition to an else if to govern the condition that n is odd that same line also needs & n != 1 to be added to it within the conditional. So this:
else if (n % 2 != 0 & n != 1)