This question already has answers here:
Java Display the Prime Factorization of a number
(7 answers)
Closed 7 years ago.
I'm trying to get the prime factors of a given number using java.I was able to write following code.It's returning 2,5,10 for the prime factors of 100 while 10 is not a prime number and also it's returning 2,4,11 for the prime factors of 88 wile 4 is not a prime number.Can any one please explain what is the reason and how to fix it?.
import java.util.ArrayList;
import java.util.Random;
public class PrimeFactors {
public static void main(String[] args) {
Random randomGenarator = new Random();
int number = randomGenarator.nextInt(150);
System.out.println("Prime factors of :" + number);
findPrimeFactors(number);
}
private static void findPrimeFactors(int i) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int n = 2; n <= i; n++) {
if (i % n == 0) {
list.add(n);
i /= n;
}
}
for (int n : list) {
System.out.println(n);
}
}
}
You aren't testing for multiple identical factors in your original number. E.g. when testing 88, you find a 2, but you miss the other 2s. (The number is now 44.) Then you skip to 3 and don't find it. Then you find 4, because 4 is a factor of 44.
You need to keep testing a factor until you no longer find it. Replace the if with while:
while (i % n == 0) {
list.add(n);
i /= n;
}
This way you'll find all 2s in the factor before anything else. Then when you get to other composite numbers such as 4 to test, you won't find them.
You are doing it wrong .
you need to remove all factors of a prime number before moving on .
for example (pseudo-code)
if i=100 ,
continue dividing it by 2 until it is non-divisible
i=100/2 =50 ,
then i=50/2 =25 then stop,
then look for next prime.
Hope it helps.
Related
This Java code prints out prime numbers between 2-100.
And this works fine.
This code is not done by me.
But I am trying to figure out what is happening with this code.
Can anyone tell me what is happening after the second (for) loop?
class primenumbers{
public static void main(String args[])
{
int i, j;
boolean isprime;
for(i=2; i < 100; i++) {
isprime = true;
// see if the number is evenly divisible
for(j=2; j <= i/j; j++)
// if it is, then its not prime
if((i%j) == 0) isprime = false;
if(isprime)
System.out.println(i + " is prime.");
}
}
}
The first loop just for generating numbers from 2 to 100.
The second loop tries to find if the number is divisible by any other number. Here we try to divide a the number with a set of numbers (2 to prime_index).
Let's say the number is 10, the prime index is 10/2 = 5 for first iteration(j = 2). Which means, if the number 10 is not divisible by any number between 2 and 5, it's a prime number. It's divisible by 2 itself making it a non prime number.
Let's say the number is 9, now the prime index is 9/2 = 4 for first iteration(j = 2). Now, 9 % 2 gives 1 as reminder. So, loop continues for second iteration (j = 3). Now the prime index is 9/3 = 3 (Note here the prime index value is reduced from 4 to 3) So, now if the number is not divisible by 3, its decided as a prime number.
So, for every iteration, the prime index will reduce, making the number of iterations reduced.
Example for Number 97,
j = 2, prime index = 97/2 = 48 (no of iterations for loop)
j = 3, prime index = 97/3 = 32 (no of iterations for loop)
j = 4, prime index = 97/4 = 24 (no of iterations for loop)
j = 5, prime index = 97/5 = 19 (no of iterations for loop)
j = 6, prime index = 97/6 = 16 (no of iterations for loop)
j = 7, prime index = 97/7 = 13 (no of iterations for loop)
j = 8, prime index = 97/8 = 12 (no of iterations for loop)
j = 9, prime index = 97/9 = 10 (no of iterations for loop)
j = 10, prime index = 97/10 = 9 (loop exits as condition failed 10 <= 9 and declares 97 as a prime number)
Now, here the loop actually took 10 iterations instead of the proposed 48 iterations.
Let's modify the code for better understanding.
public static void main(String args[]) {
// Number from 2 to 100
for(int i=2; i < 100; i++) {
if (isPrimeNumber(i)) {
System.out.println(i + " is prime");
}
}
}
Now, lets see a method isPrimeNumberNotOptimized() which is not optimized.
private static boolean isPrimeNumberNotOptimized(int i) {
for(int j=2; j <= i/2; j++) {
// if it is, then its not prime
if((i%j) == 0) {
return false;
}
}
return true;
}
And, another method isPrimeNumberOptimized() which is optimized with prime index.
private static boolean isPrimeNumberOptimized(int i) {
for(int j=2; j <= i/j; j++) {
// if it is, then its not prime
if((i%j) == 0) {
return false;
}
}
return true;
}
Now, both methods will run and print the prime numbers correctly.
But, the optimized method will decide 97 is a prime number at 10th iteration.
And, the non-optimized method will decide the same in 48th iteration.
Hope, you understand it now.
FYI: prime index is the number we used for calculation. Such that if a number is not divisible between 2 & the derived prime index, its a prime number
This is a modification of the Sieve of Eratosthenes.
First, I'll just summarize what the sieve of Eratosthenes does, you can skip to the last paragraph if you already know this. The sieve of Eratosthenes algorithm loops through a certain boundary of numbers. (Say 2 - 100). For every number it loops through, it cancels out multiples, for example, since 2 is a prime number (true), all multiples of 2 are not (They are false). Same for 3, 5, and so on; and the algorithm skips every predetermined non-prime number. Therefore, a simulation of the algorithm would be:
2 ---prime number... cancels out 4, 6, 8, 10, 12....
3 ---prime number... cancels out 6, 9, 12, 15, 18...
4 --- ALREADY CANCELLED OUT... Skip
5 --- prime number... cancels out 10, 15, 20, 25...
6 --- ALREADY CANCELLED OUT... Skip
The numbers not cancelled are therefore the prime numbers. You can also read this for more information: http://www.geeksforgeeks.org/sieve-of-eratosthenes/
Now, to your question, your algorithm loops through the list of numbers. For each number(say x), it checks if any of the previous numbers looped through (i / j) is a factor of the x. The reason why i/j is used as the boundary for the second for loop is for efficiency. If you're checking if 10 (for example) is a prime number, there's no need to check whether 6 is a factor. You can conveniently stop at n/(n/2). That's what that part is trying to achieve.
Outer (first) loop enumerates all numbers in [2,100).
Inner (second) loop checks if a current number from the first loop is dividable by anything.
This check is done using % (remainder): (i%j)==0 when remainder of division i by j is 0. By definition when remainder is zero i is dividable by j and therefore is not a prime : isprime=false.
You only need to check in [2,i/j] because you only need to check up to sqrt(i) (explanation in the last section).
Having said that the inner loop can be re-written as:
...
int s = sqrt(i);
for(j=2; j <= s; j++)
...
however sqrt is more expensive than division, therefore it's better to rewrite j<=sqrt(i) as (squaring both sides) j^2 < i and j*j<i and j<i/j. When j is big enough j*j might overflow therefore both sides were divided by j in the final step.
Explanation of sqrt(i) taken from here: Why do we check up to the square root of a prime number to determine if it is prime?
if i is not prime, then some x exists so that i = x * j. If both x and j are greater than sqrt(i) then x*j would be greater than i.
Therefore at least one of those factors (x or j) must be less than or equal to the square root of i, and to check if i is prime, we only need to test for factors less than or equal to the square root.
public class PrimeNumber {
//check prime number
public static boolean prime(int number){
boolean isPrime=true;
for(int i=number-1;i>1;i--){
if(number%i==0){
isPrime=false;
System.out.println(i);
break;
}
}
return isPrime;
}
public static boolean getPrimeUsingWhile(int number){
boolean isPrime=true;
Integer temp=number-1;
while (temp>1){
if(number%temp==0){
isPrime=false;
break;
}
temp--;
}
return isPrime;
}
//print primenumber given length
public static List<Integer> prinPrimeList(){
boolean isPrime=true;
List<Integer> list=new ArrayList<>();
int temp=2;
while (list.size()<10){
for(int i=2;i<temp;i++){
if(temp%i==0){
isPrime=false;
break;
}else{
isPrime=true;
}
}
if(isPrime){list.add(temp);}
temp++;
}
return list;
}
public static void main(String arg[]){
System.out.println(prime(3));
System.out.println(getPrimeUsingWhile(5));
System.out.println(Arrays.toString(prinPrimeList().toArray()));
}
}
This question was asked in an interview (about prime numbers)
Russian Doll Primes
They are more commonly known as Truncatable Primes.
I found this code on wiki
public static void main(String[] args){
final int MAX = 1000000;
//Sieve of Eratosthenes (using BitSet only for odd numbers)
BitSet primeList = new BitSet(MAX>>1);
primeList.set(0,primeList.size(),true);
int sqroot = (int) Math.sqrt(MAX);
primeList.clear(0);
for(int num = 3; num <= sqroot; num+=2)
{
if( primeList.get(num >> 1) )
{
int inc = num << 1;
for(int factor = num * num; factor < MAX; factor += inc)
{
//if( ((factor) & 1) == 1)
//{
primeList.clear(factor >> 1);
//}
}
}
}
//Find Largest Truncatable Prime. (so we start from 1000000 - 1
int rightTrunc = -1, leftTrunc = -1;
for(int prime = (MAX - 1) | 1; prime >= 3; prime -= 2)
{
if(primeList.get(prime>>1))
{
//Already found Right Truncatable Prime?
if(rightTrunc == -1)
{
int right = prime;
while(right > 0 && primeList.get(right >> 1)) right /= 10;
if(right == 0) rightTrunc = prime;
}
//Already found Left Truncatable Prime?
if(leftTrunc == -1 )
{
//Left Truncation
String left = Integer.toString(prime);
if(!left.contains("0"))
{
while( left.length() > 0 ){
int iLeft = Integer.parseInt(left);
if(!primeList.get( iLeft >> 1)) break;
left = left.substring(1);
}
if(left.length() == 0) leftTrunc = prime;
}
}
if(leftTrunc != -1 && rightTrunc != -1) //Found both? then Stop loop
{
break;
}
}
}
System.out.println("Left Truncatable : " + leftTrunc);
System.out.println("Right Truncatable : " + rightTrunc);
}
This gives the output:
Left Truncatable : 998443
Right Truncatable : 796339
But I am not able to solve this particular Russian doll prime number problem like if you have a prime number and you remove either left or right digit of this prime number then if that resulting number is prime number or not?
I am new to this so please pardon any mistake.
Let's start from the beginning:
According to the link you supplied with your question:
"Russian Doll Primes are
prime numbers whose right digit can be repeatedly removed, and are
still prime."
I will assume that you have a function boolean isPrime(int) to find out if a number is prime.
Googling, we will find from Wikipedia that the number of right-truncatable prime numbers up to 73,939,133 is 83, which makes brute-force a viable option; but a few optimization techniques can be employed here:
Since we right-truncate, we can safely eliminate even numbers (since any even number won't be prime, and so any number generated upon it will never be a russian doll prime).
Since any number that starts with 5 is divisible by 5, then based on the same rule I mentioned in the previous point, we can eliminate 5.
That leaves us with numbers that contain 1, 3, 7, and 9.
Now if we wanted to generate all possible combinations of these 4 numbers that do not exceed the maximum you mentioned (1,000,000), it would take only 4,096 iterations.
The downside of this technique is that we now have 4,096 numbers that contain possible non-prime numbers, or prime numbers that are formed from non-prime numbers and hence are not russian doll primes. We can eliminate these numbers by looping through them and checking; or better yet, we can examine russian doll primes more closely.
Upon examining the rule I quoted from your link above, we find that a russian doll primes are prime numbers whose right digit can be repeatedly removed, and are still prime (and hence are still russian doll prime, given the word repeatedly)!
That means we can work from the smallest single-digit russian doll primes, work our generation magic that we used above, and since any prime number that is formed from russian doll prime numbers is a russian doll prime number, we can eliminate non-primes early on, resulting in a clean list of russian doll prime numbers, while reducing the running time of such a program dramatically.
Take a look at the generation code below:
void russianDollPrimesGeneration(int x) {
x *= 10;
if (x * 10 >= 1000000) return;
int j;
for (int i=1; i<=9; i+=2) {
if (i == 5) continue;
j = x + i;
if (isPrime(j)) {
addToRussianDollPrimesList(j);
russianDollPrimesGeneration(j);
}
}
}
Provided that void addToRussianDollPrimesList(int x) is a function that adds x to a list that we previously preserved to store the russian doll prime numbers.
UPDATED NOTE
Note that you can put the call to void russianDollPrimesGeneration(int x) that we made inside the if condition inside the void addToRussianDollPrimesList(int x) function, because whenever we call the former function, we will always call the latter function with the same arguments. I'm separating them here to emphasize the recursive nature of the generation function.
Also note that you must run this function with the integer 0.
A final note is that there are a number of cases that the generation function void russianDollPrimesGeneration(int x) above won't count, even though they are Russian Doll Primes.
Remember when we omitted 2 and 5, because even numbers and numbers divided by 5 cannot be primes and so cannot be Russian Doll Primes? and consequently cannot form Russian Doll Primes? Well, that case does not apply to 2 and 5, because they are prime, and since they are single digits, therefore they are Russian Doll Primes, and are eligible to form Russian Doll Primes, if placed in the left-side, like 23 and 53.
So how to correct our code to include these special cases?
We can make a wrapper function that adds these two numbers and checks for Russian Doll Primes that can be formed using them (which will be the same generation function we are using above).
void generationWrapperFunction(int x) {
addToRussianDollPrimesList(2);
russianDollPrimesGeneration(2);
addToRussianDollPrimesList(5);
russianDollPrimesGeneration(5);
russianDollPrimesGeneration(0);
}
END UPDATED NOTE
This little function will produce a list of russian doll prime numbers, which can then be searched for the number we are looking for.
An alternative, yet I believe will be more time-consuming, is the following recursive function:
boolean isRussianDollPrime(int n) {
if (!isPrime(n)) return false;
if (n < 10) return true;
return isRussianDollPrime(n / 10);
}
This function can be modified to work with left-truncatable primes. The generation-based solution, however, will be much difficult to implement for left-truncatable primes.
Your problem is to use this code or to solve the problem ?
if to solve it you can generate primes using Sieve algorithm then check if the element is prime or not (if it was prime then check if element/10 is also prime)
Let's start with a simple assumption that we know how to write code to detect if a value is a prime. In a coding interview, they won't likely won't expect you to pull out "Sieve of Eratosthenes". You should start with simple code that handles the special cases of x<=1 (false) and x==2(true). Then check for an even number !(x % 2)(false). Then loop on i from 3..sqrt(x) (incrementing by +2 each time) to see if there's an odd number divisor for x.
boolean isPrime(long x)
{
// your code goes here
}
And once we have a function to tell us if a value is prime, we can easily build the function to detect if a value is a Russian Prime. Therefore we just need to loop on our value, each time check for prime, and then chop off the right hand side. And the easiest way to remove the right-most digit from a number is to simply divide it by 10.
boolean isRussianPrime(long x)
{
boolean result = isPrime(x);
while ((x != 0) && result)
{
// chop off the right digit of x
x = x / 10;
if (x != 0)
{
result = isPrime(x);
}
}
return result;
}
And that's really all there is to it.
package com.example.tests;
public class RussianDollPrimeNumber {
public static void main(String[] args) {
int x= 373;
int k;
int n =x;
for ( k= String.valueOf(x).length()-1;k>0;k--){
System.out.println(n);
if (isPrime(n)){
String m=String.valueOf(n).substring(0, k);
n=Integer.parseInt(m);
continue;
}else {
break;
}
}
if( k==0){
System.out.println("Number is Russianl Doll Number "+x);
}else {
System.out.println("Number is not Russianl Doll Number "+x);
}
}
private static boolean isPrime(int x) {
boolean check=true;
for (int i=2;i<x/2;i++){
if( (x%i)==0){
check=false;
}
}
return check;
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I am working on Project Euler Problem 12. Could anyone provide any tips on how to improve my code so it executes in my life time?
public class HighlyDivisibleTriangularNumber {
public static void main(String[] args) {
int divisors = 0;
int count = 1;
while(divisors <= 501) {
long triNum = triangularNumber(count);
divisors = getFactors(triNum);
System.out.println(triNum+"_"+divisors);
count++;
}
}
private static int getFactors(long triNum) {
int divisors = 0;
while(triNum > 1) {
triNum = triNum / 2;
divisors++;
}
return divisors;
}
private static long triangularNumber(int i) {
long total = 0;
for(int k = 1; k <= i; k++) {
total += k;
}
return total;
}
}
1) triangular numbers
The first (and probably most important) optimization you can do is in how you compute the triangular numbers.
You can observe that the nth triangular number (let's call it t(n) ) is equal to n + t(n-1).
So each time you compute a triangular number, you can just take the triangular number before it and add n. This would lead to the naive recursive function :
private static long triangularNumber(int i) {
if(i == 1) return 1;
else return i+triangularNumber(i-1);
}
But this won't improve the performance much... to resolve this, I suggest you do some research on memoization and adapt the function I gave you (I won't give you the answer, this is an excellent exercise)
Now, on a regular computer you should have the answer to the problem in a reasonable time. But it can be improved a little better
2) counting divisors
Your function for counting divisors is wrong. What you should do is try to divide your number by successive natural numbers and see if the result is an natural integer.
private static int getFactors(long triNum) {
int divisors = 0;
for(int i = 1; i <= triNum; ++i) {
if(triNum%i == 0) // triNum is a multiple of 1 <=> i is a divisor of triNum
divisors++;
}
return divisors;
}
You can even improve this by counting only to the square root of trinum and adding two divisors each time. But there's a trick if you do this, I'll let you figure it out if you decide to try this.
Why do do recompute the triNum each time? Just add the difference each time (basically your count).
public static void main(String[] args) {
int divisors = 0;
int count = 1;
long truNum = 0;
while(divisors <= 501) {
triNum += count;
divisors = getFactors(triNum);
System.out.println(triNum+"_"+divisors);
count++;
}
}
Furthermore, your approach to count the factors is completely off. You are just searching for the first power of two to be greater than the given number. Read up on (prime)-factorization. Note that you need to account for the combinations of (prime) factors, too.
Example: 12
12 = 2 * 2 * 3
But the divisors of 12 are
1, 2, 3, 4 (= 2*2), 6 (= 2*3), 12
So in total there are 6 divisors of 12 and not 3 as the mere prime factorization may lead you to believe.
This question already has answers here:
Project Euler 3 - Highest Prime Factor
(2 answers)
Project Euler #3 takes forever in Java
(9 answers)
Closed 9 years ago.
I am trying Problem 3 from Project Euler and my algorithm is far too slow. Does anyone know how to optimize this? The number I am trying to calculate up to is 600851475143L. It takes forever to calculate this so I need a way to speed up the calculations.
LOGIC:
Go through all the numbers from 3 until that number-1
For each of these numbers check if they are prime by dividing them by all the numbers in between and if they dont divide by any of them then they are prime.
If prime then add them to an array.
public static void problem3(long number){
long number2 = number;
long sqrtNumber = (long)Math.sqrt(number2);
int indexNum = 1;
boolean isPrime = false;
int primeNums[] = new int[2];
primeNums[0] = 2;
//puts prime numbers into an array
for(int y = 3; y < sqrtNumber; y++){
isPrime=true;
for(int theNum = 2; theNum < y; theNum++){
//if y divides evenly by any number then it is not prime
if(y%theNum==0){
//dont store in array
isPrime=false;
break;
}
}
if(isPrime == true){
//add to array
System.out.println(y);
//put y in the array and exapnd the array
//System.out.println("y: " + y);
primeNums[indexNum] = y;
int[] newArray = new int[primeNums.length + 1];
System.arraycopy(primeNums, 0, newArray, 0, primeNums.length);
primeNums = newArray;
indexNum++;
}
}
********** UPDATE **************
I calculated up to the square root which sped up the calculations a lot but I also done something else which was to add a break statement in the forloop to break once I discovered the number was not prime. I edited the code above to reflect these changes.
My algorithm is still wrong for calculating the prime factors though so I will need to have a look at it and maybe raise a new question.
You don't have to divide by every number. You only have to divide by each prime number between 2 and the square root of your number.
The first thing you can do is only test possible factors up through the square root of the number that you're testing, because if you find a factor greater than the square root, then you should have found a factor less than the square root.
If you need additional performance, then use the Sieve of Eratosthenes. That allows you to use the results of previous primes to cut down the work on determining if larger numbers are prime.
Resolution:
It turns out there is (probably) "nothing wrong" with the code itself; it is just inefficient. If my math is correct, If I leave it running it will be done by Friday, October 14, 2011. I'll let you know!
Warning: this may contain spoilers if you are trying to solve Project Euler #3.
The problem says this:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
Here's my attempt to solve it. I'm just starting with Java and programming in general, and I know this isn't the nicest or most efficient solution.
import java.util.ArrayList;
public class Improved {
public static void main(String[] args) {
long number = 600851475143L;
// long number = 13195L;
long check = number - 1;
boolean prime = true;
ArrayList<Number> allPrimes = new ArrayList<Number>();
do {
for (long i = check - 1; i > 2; i--) {
if (check % i == 0) {
prime = false;
}
}
if (prime == true && number % check == 0) {
allPrimes.add(check);
}
prime = true;
check--;
} while (check > 2);
System.out.println(allPrimes);
}
}
When number is set to 13195, the program works just fine, producing the result [29, 13, 7, 5] as it should.
Why doesn't this work for larger values of number?
Closely related (but not dupe): "Integer number too large" error message for 600851475143
The code is very slow; it is probably correct but will run for an unacceptably large amount of time (about n^2/2 iterations of the innermost loop for an input n). Try computing the factors from smallest to largest, and divide out each factor as you find it, such as:
for (i = 2; i*i <= n; ++i) {
if (n % i == 0) {
allPrimes.add(i);
while (n % i == 0) n /= i;
}
}
if (n != 1) allPrimes.add(n);
Note that this code will only add prime factors, even without an explicit check for primality.
Almost all the Project Euler problems can be solved using a signed datatype with 64 bits (with the exception of problems that purposefully try to go big like problem 13).
If your going to be working with primes (hey, its project Euler, your going to be working with primes) get a headstart and implement the Sieve of Eratosthenes, Sieve of Atkin, or
Sieve of Sundaram.
One mathematical trick used across many problems is short circuiting finding factors by working to the square root of the target. Anything greater than the square corresponds to a factor less than the square.
You could also speed this up by only checking from 2 to the square root of the target number. Each factor comes in a pair, one above the square root and one below, so when you find one factor you also find it's pair. In the case of the prime test, once you find any factor you can break out of the loop.
Another optimization could be to find the factors before checking that they are prime.
And for very large numbers, it really is faster to experiment with a sieve rather than brute forcing it, especially if you are testing a lot of numbers for primes. Just be careful you're not doing something algorithmically inefficient to implement the sieve (for example, adding or removing primes from lists will cost you an extra O(n)).
Another approach (there is no need to store all primes):
private static boolean isOddPrime(long x) {
/* because x is odd, the even factors can be skipped */
for ( int i = 3 ; i*i <= x ; i+=2 ) {
if ( x % i == 0 ) {
return false;
}
}
return true;
}
public static void main(String[] args) {
long nr = 600851475143L;
long max = 1;
for ( long i = 3; i <= nr ; i+=2 ) {
if ( nr % i == 0 ) {
nr/=i;
if ( isOddPrime(i) ){
max = i;
}
}
}
System.out.println(max);
}
It takes less than 1 ms.