Calling for even and odd figures - java

Write a method named hasAnOddDigit that returns whether any digit of a positive integer is odd. Your method should return true if the number has at least one odd digit and false if none of its digits are odd. 0, 2, 4, 6, and 8 are even digits, and 1, 3, 5, 7, 9 are odd digits.
For example, here are some calls to your method and their expected results:
Call Value Returned
hasAnOddDigit(4822116) true
hasAnOddDigit(2448) false
hasAnOddDigit(-7004) true
You should not use a String to solve this problem.
This is my attempt at the question:
public boolean hasAnOddDigit(int num){
int number=0;
while (number > 0) {
number= number % 10;
number = number / 10;
}
if(number%2==0 && num%2==0){
return false;
}else{
return true;
}
}
Called for hasAnOddDigit(4822116) and it gives me a false instead of true.

Your method should check each digit as it goes through the loop, rather than waiting for the loop to complete before making its decision. Currently, the while loop runs the number down to zero, and only then tries to check the value. Naturally, by the time the loop is over, both values are zero, so the return is false.
public boolean hasAnOddDigit(int num){
// You do not need to make a copy of num, because
// of pass-by-value semantic: since num is a copy,
// you can change it inside the method as you see fit.
while (num > 0) {
int digit = num % 10;
if (digit % 2 == 1) return true;
num /= 10;
}
// If we made it through the loop without hitting an odd digit,
// all digits must be even
return false;
}

A recursive version which might be more intuitive for some.
private boolean hasAnOddDigit(int num) {
if (num<10) {
return num%2==0 ? false : true;
} else {
return check(num%10) || check (num/10);
}
}

Related

Control Flow Explanation

Write a method named hasSharedDigit with two parameters of type int.
Numbers are between 10 and 99
The method should return true if there is a digit that appears in both numbers, such as 2 in 12 and 23; otherwise, the method should return false.
I have a solution, but don't quite understand how it works. I need an English explanation.
public class SharedDigit {
public static boolean hasSharedDigit(int numA,int numB){
if((numA<10||numA>99)||(numB<10||numB>99)){
return false;
}
int realNumB=numB;
while(numA>0){
int numADig=numA%10;
while(numB>0){
int numBDig=numB%10;
if(numADig==numBDig){
return true;
}
numB=numB/10;
}
numA=numA/10;
numB=realNumB;
}
return false;
}
}
I don't understand how this code is checking all possibilities of matching numbers
This here:
while(numA>0){
int numADig=numA%10;
uses the modulo operator to "get" the last digit of a number, see here for more information. So this first step gets you the "3" from 13 for example.
Later, you do:
numA=numA/10;
That turns 13 into 1 (int division)! That initial loop condition before ensures that you stop when you did 13 / 10 .. and then 1 / 10.
So this loops turns 13 into 3, then 1, and then stops.
And the same "method" is used to get the digits of the second number. And as soon as you find a digit in both numbers, you can return true.
Otherwise, if you walked trough all digits of the first number, and compared them against all digits in the second number ... no match, return false.
The real answer here, btw: when you do not understand what code does:
use a search engine to research all the things in the source you do not know
use a debugger, or simple System.out.printl() statements to enable yourself to observe what the code is doing
then finally, when all of that fails, and leaves you with doubts, then come here and ask for help
Have a look on my correct solution.
public class SharedDigit {
public static boolean hasSharedDigit (int one, int two) {
int modulusOne = one % 10;
int modulusTwo = two % 10;
int divisionOne = one / 10;
int divisionTwo = two / 10;
if ((one < 10 || one > 99) || (two < 10 || two > 99)) {
return false;
} else if (one == two){
return true;
} else if (modulusOne == modulusTwo){
return true;
} else if (divisionOne == divisionTwo){
return true;
} else if (divisionOne == modulusTwo){
return true;
} else if (divisionTwo == modulusOne){
return true;
} else {
return false;
}
}
}

Return statement does not correctly terminate a recursive method

I have a method getNextPrime(int num) which is supposed to identify the closest prime number after the value received by the method.
If num is even, it will increment it and call itself again. If it is odd, it will run a for loop to check if it is divisible by odd numbers between 3 and num's half value. If it is then it will increase num by 2 and the method will call itself again, otherwise it will return the new num value which is a prime number.
The problem is, when the program gets to the return statement, it will jump to the if statement and return the original value of num + 1. I have been debugging this for a while and it just doesn't make sense. Wherever I place the return statement, the method just jumps to the if statement instead of terminating the method and returning the value to where it is being called from.
public int getNextPrime(int num){
if(num % 2 == 0){
//even numbers are not prime
getNextPrime(++num);
}
else{
for(int i = 3; i < (num + 1) / 2; i += 2){
if(num % i == 0) {
getNextPrime(num += 2); //consider odd numbers only
}
}
}
return num; //jumps to if and terminates
}
However, if I change the else statement to a separate if statement, if(num % 2 != 0) it works.
Why does this happen?
*Note - the values given to the method are greater than 3, the fact that 1, 2, and 3 are primes doesn't matter.
There is only one structural problem here. Reaching a single return does not collapse the entire call stack, it only returns to the previous invocation.
You need to save the result of calling getNextPrime() every time and use that as the return value, so the value actually found gets passed back along the call chain and returned to the initial caller. As it stands you return only the number that was passed in since you never modify it.
The fix is a very simple modification. Where you have
getNextPrime(++num);
... and ...
getNextPrime(num+2);
replace them with
return getNextPrime(++num);
... and ...
return getNextPrime(num+2);
The problem with the algorithm you chose is that it is inefficient. You need to test divisibility using smaller primes only, not all odd numbers, and only up to the square root of the original number.
Implementation is left as an exercise.
Lets try to look at the call stack when we call your function with argument 8;
The first call is : getNextPrime(8). As the number is even, the function goes into the if part and calls itself again with getNextPrime(9). This time the else part kicks in, checks for divisibility in for loop, finds that 9 is divisible so calls the getNextPrime(11). Now getNextPrime(11) goes again the else and the for loop and finds that 11 was prime and returns the number 11 to the caller, but if you look closely, you don't store this value in a variable, the num variable in the getNextPrime call was 9, and when getNextPrime(9) returns it returns that value to getNextPrime(8). In your getNextPrime(8) too you haven't really stored the num variable returned from the recursion call stack. You are just return the num variable defined in that function, which you happened to increment before calling the getNextPrime(11) so this value is 9, and 9 is returned.
Corrected program with the same if else block is given below for your reference.
public static int genNextPrime(int num) {
if (num % 2 == 0) {
num = genNextPrime(++num);
} else {
for (int i = 3; i < (num + 1) / 2; i += 2) {
if (num % i == 0) {
num += 2;
num = genNextPrime(num);
}
}
}
return num;
}
Your return statement works fine but ..you have left 1,2 and 3 out of your logic. 2 is a even prime number and 1 is not a prime number.

Power of two failed to pass the test

Isn't this one way to test whether a number is a power of 2?
boolean isPowerOfTwo(int n) {
return (n%2==0);
}
Are you sure that you are checking power of 2? Rather, being checked divisible with 2. If you are serious, use the piece of cake snippet
return n > 0 && ((n & -n) == n);
The second way,
private static boolean powerOf2(int num)
{
if(num <= 0){
return false;
}
while(num > 1)
{
if(num % 2 != 0)
{
return false;
}
num = num / 2;
}
return true;
}
That function checks whether or not an integer is even (i.e divisible by 2), not whether or not the integer is a power of 2.
To check if a number is a power of 2, you should look at its bits. ints that are a power of 2 will have one bit set to 1 and all others set to 0.
boolean isPowerOf2(int i) {
return Integer.bitCount(i) == 1;
}
The % is the modulo operator, meaning the remainder after division. your method checks if the int n is divisible by 2

I don't understand this 'for' loop for prime number validation in Java

I don't understand this 'for' loop in Java
This loop is just to check if a number is prime or not. I understand the first statement because 1 is not a prime number but it's what happens in the 'for' statement. Why is 'primeNumber' being divided by two and why is the second 'if' calculating for a remainder of zero? how does this code help to confirm a prime number? what is it doing?
public static boolean isPrime (int primeNumber) {
if (primeNumber == 1) {
return false;
}
for (int primeDivider=2; primeDivider <= primeNumber/2; primeDivider++) {
if (primeNumber % primeDivider == 0) {
return false;
}
}
return true;
}
A prime number can only be divided by itself and one. 7 is prime because only 1 and 7 divide into 7. Also 8 is not prime because as well as 1 and 8, both 2 and 4 divide into 8.
Look at the for loop and see what values primeDivider takes: 2, 3, 4, 5, ... The loop tries each of these in turn to see if it divides into the number you are testing. If it divides evenly, with a remainder 0, then the number being tested is not prime and the method returns false. If none of the numbers divide, then the number being tested in prime and the method returns true. As an aside, primeNumber is a bad variable name. Something like possiblePrime would be better. The number being tested might not be prime.
The primeDivider sequence stops at half the number being tested. If a number is not prime (a composite number) then at least one of its divisors is guaranteed to be less than or equal to half the number.
As others have said, this is not a very efficient test. Here is a slightly more efficient version for you to study:
public static boolean isPrime (int possiblePrime) {
// Test negatives, zero and 1.
if (possiblePrime <= 1) {
return false;
}
// Test even numbers
if (possiblePrime % 2 == 0) {
// 2 is the only even prime.
return possiblePrime == 2;
}
// Test odd numbers >= 3.
int limit = possiblePrime / 2;
for (int primeDivider = 3; primeDivider <= limit; primeDivider += 2) {
if (possiblePrime % primeDivider == 0) {
return false;
}
}
// Only prime numbers reach this point.
return true;
}
By treating odd and even numbers separately, you can catch all the even numbers with a single test and by stepping primeDivider by 2 each time, roughly halve the time taken for odd numbers.
As billjamesdev says, that can be made even more efficient by using:
int limit = (int)Math.floor( Math.sqrt( possiblePrime ));
A composite number will always have a divisor, other than 1, less than or equal to its square root.

Method to search for prime numbers

I need to build a method that calculates prime numbers.
I'm testing it and it's giving me the wrong answers and I don't know how to solve it! For example, it returns true to 98262679 instead of false. Where is my mistake?
public static boolean itsPrime(int nbTest){ // Tests for prime numbers method
boolean prime = false;
if (nbTest <= 1){
return false;
} else if (nbTest == 2){ // Two is prime
return true;
} else if ((nbTest != 2) && (nbTest % 2 == 0)){ // Evens except number 2
return false; // are not prime
} else if (nbTest % 2 != 0){ // For all remaining odds
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2){
if (nbTest % i == 0){
prime = false;
} else {
prime = true;
}
}
}
return prime;
}
I'm learning Java and my professor asked us to construct the method itsPrime was based on this:
For the first subtask, write a function `itsPrime` that takes an `int`
as argument and returns a `boolean`, `true` if the argument integer is prime
and `false` otherwise.
To test whether an integer x is prime, one can proceed as follows:
all integers less than or equal to 1 are not prime;
2 is prime;
all other even integers are not prime;
for all remaining integers (obviously odd), search for a divisor:
loop from 3 to the square root of the integer x (The square root of x can
be computed as ‘‘Math.sqrt(x)'' in Java.); if the remainder of the integer
division of x by the loop index is zero, then x is not prime;
if all remainders were non-zero at the end of the loop, then x is prime;
I know the answer is there somewhere in all the answers above, but I think that each require an explanation.
Here's a summary of all the enhancements you could make to your code:
1) Don't declare a boolean to return, since you are already returning true or false throughout your code. Remove this line from your code (call it [1]):
boolean prime = false;
You'll see why after you've fixed the rest of your function. Comment it out if desired, for now.
2) In your second else if, let's call it [2], you have:
else if ((nbTest != 2) && (nbTest % 2 == 0)){
return false;
}
You already checked if nbTest is 2 in your first else if, so you don't need to check if it's not 2 again. If it entered the first if else, your function will return true. When a function returns, it is done. It returns the value to the caller and the rest of the code is not executed.
Thus, you may replace that second if else, [2], with:
else if (nbTest % 2 == 0) { // all other even integers are not prime
return false;
}
3) If you enter third else if, this means that the rest of the code above already executed, and it either returned, or the program continued.
You may replace that third else if (nbTest % 2 != 0){ for:
else {
4) This is the one error that you really have to make your function return the wrong answer (call this snippet [4]):
if (nbTest % i == 0){
prime = false;
If you find that the number you are testing is divisible (i.e. the remainder is zero), you are done. You definitely know that it is not prime.
You may replace this code, [4], with:
if(nbTest % counter == 0) {
return false;
}
Thus, returning false. It is not a number. And the function does not keep executing. Your error was continuing execution after the function finds out that your input is not prime.
Finally, you may leave your return true at the end of the function body. If the function never returned from the previous tests, or from the loop, it has to be a prime number. Remember that first line I told you to remove? The boolean declaration? Since you never return a value from a variable, you just return true or false, you don't need that [1] line.
As an extra, a good read on finding prime numbers, which you might want to share with your professor:
https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
You should stop once you here:
if (nbTest % i == 0){
return false;
}
Delete the prime variable (it is an unnecessary step, see below).
Change the for loop:
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2){
if (nbTest % i == 0){
prime = false;
} else {
prime = true;
}
}
To this:
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2)
if (nbTest % i == 0)
return false;
This simply breaks out of the function early if it isn't prime (if a factor has been found).
You shouldn't keep testing for primality once prime has been set to false for a number.
Replace:
if (nbTest % i == 0){
prime = false;
with:
if (nbTest % i == 0){
return false;
And the last test is useless, you can just keep a basic else:
else if (nbTest % 2 != 0){ => else {
Your for loop is not correct.
A prime number is a number which is divisible by 1 and itself only. So, if a number A is divisible by any other number except 1 and itself, then A is a nonprime.
Just replace your for loop with the one below
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2) {
if (nbTest % i == 0)
return false;
}
Once it is found that nbTest is divisible by some number, there is not point in continuing the loop. Return `nbTest is nonprime, then and there.

Categories