I need help with a program that satisfies the following quote:
All integers >= 2 can be factored into the product of only prime
numbers. For instance, the number 12 has a prime factorization of
2*2*3, while the number 100 has a prime factorization of 2*2*5*5. We
are interested in knowing whether an input integer has a prime
factorization that only has 2s and 3s.
I think I need more base conditions and a catch all recursive call.
Current (unfinished) Code:
public static boolean hasFactors2and3(int number) throws IllegalArgumentException{
if (number < 2) throw new IllegalArgumentException("Number is less than 2");
if (number >= 2 && number < 5) return true; // because for all these numbers it works
if (number % 2 == 0) return hasFactors2and3(number /= 2);
if (number % 3 == 0) return hasFactors2and3(number /= 3);
}
Any help is appreciated!
You ask for a recursive solution. I won't give you that. Instead I will give you a non-recursive solution in pseudocode and leave it up to you to convert it into a recursive solution.
function hasFactors2and3(number)
// Deal with negatives, 0, 1.
if (number < 2)
return false
endif
// Remove factors of 2.
while (number MOD 2 == 0)
number <- number / 2
endwhile
// Remove factors of 3.
while (number MOD 3 == 0)
number <- number / 3
endwhile
// See what factors are left after removing all 2s and 3s.
return number == 1
end function
Hint: research how to remove tail recursion by using a loop and then reverse the process.
Related
I am only interested in n < 0 case, if n == -3 then I get, 0.001 as desired.
but I reached here through trial and error. Can someone explain to me 'WHY' this works (for n < 0 case only)?
public static double power10(int n) {
if(n == 0){
return 1;
}
else if (n > 10){
return 10 * power10(n - 1);
}
else {
return 1.0 / power10(-n);
}
}
The Following Function works for both negative and positive powers.
double Power(int n1,int n2) {
if(n2>=0) {
if(n2==1) {
return n1;
}
if(n2==0) {
return 1;
}
else {
return n1*Power(n1,n2-1);
}
}
else {
if(n2==-1) {
return 1.0/n1;
}
else {
return 1.0/(n1*Power(n1,(-1)*(n2+1)));
}
}
It will create following recursion tree for Negative example,
This link will redirect you to the recursion tree to better understanding, How this function will work recursively.
In fact, your code doesn't work for either 3 or -3. A stack overflow occurs in both cases. I don't know how you got 0.003.
The error in your code is this:
else if (n > 10){
It should be n > 0. instead.
This recursive algorithm should be quite clear if we turn it into a sentence starting with "the nth power of 10 is...":
The nth power of 10 is:
If n is 0, 1
If n is positive, 10 * (n-1)th power of 10
If n is negative, 1 / -nth power of 10
You can see that all values of n are covered, whether it be 0, positive or negative. In your incorrect code, you treat cases where 0 < n < 10 as "negative numbers". When you negate those and recurse, you get a real negative number, it goes into the else again and they are negated again. But they are still not larger than 10, causing infinite recursion.
Your code here probably give out stack overflow error.
Try
else if(n>0)
Now under the above condition function return n th value of 10 and return 1000 (when n is 3 case), Giving you the answer 0.001.
Could anyone explain how does this method works.
public static int calculate(int n){
if (n/10 == 0)
return n;
else
return (n % 10 + calculate(n/10));
}
I input n = 15 and it get a 6 but I don't understand how the method works. please help. thank you.
The method calculates the sum of the digits.
If the n is smaller than 10, you simply return n (since the sum of digits of a single digit number is the number itself).
Otherwise you add the least significant digit (that's n % 10) to the sum of digits of the number n / 10 (which is calculated recursively).
For n = 15 , here is how it works
15/10 > 0 , so the else condition is executed.
15%10 + calculate(15/10) i.e 5 + calculate(1).
The method is called again for n = 1;
Since 1/10 == 0 , 1 is returned
This 1 is then added to 5.
Therefore answer is 6.
So what this function does is return the sum of the digits that make up the number.
It goes like this:
calculate(15);
evaluates to
15%10 + calculate(1);
evaluates to
5 + 1;
which in the end; sums up to 6.
In other words; the above is an recursive approach to sum all the digits in a number. You could easily re-write this using a simple loop to avoid the recursion construct.
It cuts off the most right digit and moves on recursively with the rest of the number. (line 5)
If we have only one digit left (line 2), it is also added to the sum and the algorithm ends. (line 3)
In this example there is a if else condition so on the basis of input parameter there are 2 conditions '
-Firstly it checks in the if condition (n/10 == 0) .
-Consider your input as n=15.
now it checks if (n/10 == 0) i.e 15/10==0 which is false because 15/10=5 which is not equal to 0.
-As the condition is false it moves to else block where condition is to return
(n % 10 + calculate(n/10)
i.e. (15%10 +15/10)==5+1==6
-So the return is 6.
This code counts the number 7 of your input. This is the code method:
public static int count7(int n) {
if (n == 0) {
return 0;
}
else if (n % 10 == 7) {
return 1 + count7 (n/10);
}
else {
return count7(n/10);
}
}
What does the else-if statement and else do? Thank you so much.
if (n == 0) {
return 0;
There are no 7s in 0, so return 0.
} else if (n % 10 == 7) {
checks if the least significant digit of the number is 7. If that's the case, the total number of 7s is 1 + the number of 7s in the number you get by removing that digit (by dividing the number by 10) :
return 1 + count7 (n/10);
} else {
If the least significant digit is not 7, the number of 7s is the number of 7s in n/10 :
return count7(n/10);
}
if (n % 10 == 7) if the remainder is 7 lets take example n=17 so 17%10 you are going to get 7 so add 1 means count that you have found 7 if you have not found then go to the else part and this time call by dividing it suppose this time n=28 clearly there is no 7 in this number so it will go to else if condition and it is going to be fail it will go to the else part and it will call the method by dividing n to 10 for the next iteration.
This is a recursive method.
The first if is the base case, i.e, if the numbers is 0, then it returns 0.
The else if checks if the digit is 7. If it is, then get the answer to the remaining digits (whether they have any 7s) using the same method, add 1 to it, and return the value.
The last else just removes one digit, and calls the method for the remaining digits.
This method counts the total amount of the digit 7 in a given number.
n % 10 == 7 inspects the least significant digit, and if it equals 7, then add 1 to the sum.
In any case, the algorithm goes on with the other digits by taking n / 10, which actually removes the least significant digit, and then calls the method recursively. As the number is decreasing with 1 digit with each call and the stop trigger n == 0 makes the method eventually stop, the final returned number counts the sevens in the initial number.
Example
count7(172) = 0 + count7(17) = 0 + 1 + count7(1) = 0 + 1 + 0 = 1
The function simply counts the total number of appearances of the digit 7 in any given non-negative integer.
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.
I know this is a classic problem. I solved it in Java. I have my solution below. However, when I used this solution in codefights.com, It went beyond the execution time limit. I would appreciate if anyone could give me suggestions on improving this code in any way possible. Please feel free to criticize my code so that I can improve on my coding skills. Thanks
You're given number n.
Return n as a product of its prime factors.
Example
For n = 22 the output should be "2*11".
For n = 120 the output should be "2*2*2*3*5".
For n = 17194016 the output should be "2*2*2*2*2*7*59*1301".
[input] integer n
An integer number smaller than 109. [output] string
The Prime factors of n which splitted by * symbol. prime factors
should be in increasing order.
Solution (JAVA):
public String primefactors(int n) {
String factors = "";
for (int i = 2; i <= n / 2; i++) {
if (isPrime(i)) {
while (n % i == 0) {
n /= i;
if (isPrime(n) && n != 1) {
factors = factors + Integer.valueOf(i).toString() + "*"
+ Integer.valueOf(n).toString();
break;
} else if (n == 1)
factors = factors + Integer.valueOf(i).toString();
else
factors = factors + Integer.valueOf(i).toString() + "*";
}
}
}
return factors;
}
public boolean isPrime(int n) {
boolean prime = true;
if (n == 1)
return false;
else if (n % 2 == 0 && n!=2)
return false;
else if (n % 3 == 0 && n!=3)
return false;
else {
for (int j = 2; j < n / 2; j++) {
if (n % j == 0) {
return false;
}
}
}
return prime;
}
Since n is smaller than a fixed number (109), simply use a table containing all prims <= 109, instead of generating them dynamically. Or atleast generate the prims first using the sieve of erathostenes or atkin. The hardcoded table would be preferable, but using a sieve for generating the table dynamically would aswell speed things up alot. The isPrime() function you implemented is a performance killer.
The function isPrime() is called too much times in primefactors. For example, i == 2 and there are many divisors 2 in n. The top call (isPrime(i)) is fine. However, inside the loop while (n % i == 0) you check isPrime(n) after each dividing n /= 2;. So, if initial n is 100 the function isPrime() is called for 50 and on the next loop for 25. That does not make any sense. I think that it is the biggest problem here, since even if isPrime works in linear time it is too much to call it many times in the internal loop.
It is possible to exit from the loop for i in two cases: n is equal 1 after divisions or n is for sure prime if i is larger than sqrt(n).
public String primefactors(int n) {
String factors = "";
int max_divisor = sqrt(n);
for (int i = 2; i <= max_divisor; i++) {
if (isPrime(i)) {
while (n % i == 0) {
n /= i;
if (n == 1)
factors = factors + Integer.valueOf(i).toString();
else
factors = factors + Integer.valueOf(i).toString() + "*";
}
max_divisor = sqrt(n);
}
}
// check for the last prime divisor
if (n != 1)
factors = factors + Integer.valueOf(n).toString();
return factors;
}
Even after that improvement (and sqrt(n) as the max limit in isPrime()) your algorithm will have linear complexity O(n), since there are at most sqrt(n) loops for i and the maximum number of probes for prime in isPrime is also sqrt(n).
Yes, it can be done better by choosing better algorithms for isPrime(). Even if you are not allowed to use hardcoded table of prime numbers it is possible to generate such look up table in runtime (if there are enough memory). So, it is possible to use automatically generated list of primes organized in ascending order to probe given number up to sqrt(n). If i becomes larger than sqrt(n) it means that the next prime is found and it should be appended to the look up table and isPrime() should return true.
Example
Suppose isPrime is called for 113. At that moment the look up table has a list of previous prime numbers: 2,3,5,7,11,13.... So, we try to divide 113 by items from that list up to sqrt(113) (while (i <= 10)). After trying 2,3,5,7 the next item on the list 11 is too large, so 113 is appended to the list of primes and the function returns true.
The other algorithms may give better performance in the worst case. For example the sieve of Eratosthenes or sieve of Atkin can be used to effectively precomputed list of prime numbers up to given n with the best O(n) complexity for the best implementation. Here you need to find all primes up to sqrt(n), so it takes O(sqrt(n)) to generate such list. Once such list is generated you need to try to divide your input by numbers is the list that takes at most sqrt(n) probes. So, the algorithm complexity is O(sqrt(n)). However, suppose that your input is 1024 that is 2 to the power of 10. In that case the first algorithm will be better, since it will not go to primes larger than 2.
Do you really need the function isPrime()?
With flexible thinking If we look closer it appears that you do not have to search for all primes in some range. You only needed to find all prime divisors of one given integer. However if we try to divide n by all integers in range up to sqrt(n) that is also good solution. Even if such integer is not prime it will be skipped due to the condition n % i == 0, since all primes lower than the integer under test are already removed from n, so that simple modular division does here the same as isPrime(). The full solution with O(sqrt(n)) complexity:
public String primefactors(int n) {
String factors = "";
int max_divisor = sqrt(n);
for (int i = 2; i <= max_divisor; i++) {
while (n % i == 0) {
n /= i;
max_divisor = sqrt(n);
if (n == 1)
factors = factors + Integer.valueOf(i).toString();
else
factors = factors + Integer.valueOf(i).toString() + "*";
}
}
// check for the last prime divisor
if (n != 1)
factors = factors + Integer.valueOf(n).toString();
return factors;
}
It is also possible to split the function to avoid if (n == 1) check in the inner loop, however it does not change the algorithm complexity.