I have solved the problem and it gives me the right output when the BigInteger
has the smaller value, however it kept running for more than 20 minutes with the larger value without printing out an answer. So I'm thinking that there should be a faster algorithm for this program.
The problem states:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
Main Method:
printPrimeFactors(new BigInteger("13195"));
Output:
29 13 7 5
BUILD SUCCESSFUL (total time: 0 seconds)
But when I change the value:
Main Method
printPrimeFactors(new BigInteger("600851475143"));
The program keeps running for a long time (more than 20 minutes), I didn't wait for an answer and stopped it.
Here is the rest of the program:
public static boolean isPrime(BigInteger n) {
if(n.compareTo(new BigInteger("2")) == -1) return false;
if(n.equals(new BigInteger("2")) || n.equals(new BigInteger("3"))) return true;
if(n.remainder(new BigInteger("2")).equals(BigInteger.ZERO) || n.remainder(new BigInteger("3")).equals(BigInteger.ZERO)) return false;
BigInteger sqrtN = bigIntSqRootFloor(n).add(BigInteger.ONE);
for(BigInteger i = new BigInteger("6"); i.compareTo(sqrtN) == 0 || i.compareTo(sqrtN) == -1; i = i.add(new BigInteger("6"))){
if(n.remainder(i.subtract(BigInteger.ONE)).equals(BigInteger.ZERO)) return false;
else if(n.remainder(i.add(BigInteger.ONE)).equals(BigInteger.ZERO)) return false;
}
return true;
}
public static void printPrimeFactors(BigInteger number){
for(BigInteger i = BigInteger.ZERO.add(number);!i.equals(new BigInteger("1")); i = i.subtract(BigInteger.ONE)){
if(isPrime(i) && number.remainder(i).equals(BigInteger.ZERO)){
System.out.print(i + " ");
number = number.divide(i);
printPrimeFactors(number);
break;
}
}
}
public static BigInteger bigIntSqRootFloor(BigInteger x)
throws IllegalArgumentException {
if (x.compareTo(BigInteger.ZERO) < 0) {
throw new IllegalArgumentException("Negative argument.");
}
if (x .equals(BigInteger.ZERO) || x.equals(BigInteger.ONE)) {
return x;
}
BigInteger two = BigInteger.valueOf(2L);
BigInteger y;
for(y = x.divide(two);
y.compareTo(x.divide(y)) > 0;
y = ((x.divide(y)).add(y)).divide(two));
return y;
}