public class symm
{
/*
* Returns true if array A is symmetric.
* Returns false otherwise.
* n is the number of elements A contains.
*
* The running time of your algorithm is O( ).
* You may add a brief explanation here if you wish.
*/
public static boolean symmetric( int[] A, int n )
{
return symmHelper(A, n, 0);
}
private static boolean symmHelper(int[] A, int n, int i) {
if(n==1)
return true;
if((n==2) && (A[i] == A[n-1-i]))
return true;
if((i == n-1-i) && (A[i] == A[n-1-i] ))
return true;
if(A[i] == A[n-1-i] && i < n/2 )
return symmHelper(A, n, i+1);
return false;
}
}
Test cases:
I passed all the tests ecxept the fitst on I get no whenever I run it, I think the problem is that there are two 2s in the middle. And I'm not really sure about the code, I think it can be simplified.
Is the running time o(log n)?
5 8 2 2 8 5
YES
10 7 50 16 20 16 50 7 10
YES
5 8 5
YES
1000 1000
YES
6000
YES
10 7 50 16 20 16 50 7 1000
NO
10 7 50 16 20 16 50 700 10
NO
10 7 50 16 20 16 5000 7 10
NO
10 7 50 16 20 1600 50 7 10
NO
10 7 50 16 1600 50 7 10
NO
Complex code makes for more mistakes. Thus, simplify it. Also, look for inequalities rather than equalities; it's easier to check for one mistake than for everything to be correct.
// A = array, n = size of array, i = looking at now
private static boolean symmHelper(int[] A, int n, int i) {
if (i > n/2) // If we're more than halfway without returning false yet, we win
return true;
else if (A[i] != A[n-1-i]) // If these two don't match, we lose
return false;
else // If neither of those are the case, try again
return symmHelper(A, n, i+1);
}
If I remember my O() notation right, I think this should be O(n+1). There are other tweaks you can make to this to remove the +1, but it'll make the code run slower overall.
if(A[i] == A[n-1-i] && i < n/2 )
That line right there is the problem. Because you're using an even number > 2 of values, when it gets to this line it skips over it because at that point i = n/2, rather than being less than it. So the function skips that and continues on to return false. Change it to this and you should be fine:
if(A[i] == A[n-1-i] && i <= n/2 )
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int N;
int i;
boolean sym = true;
N=input.nextInt();
int [] numbers = new int [N];
for (i=0; i<N; i++){
numbers[i]= input.nextInt();
}
for(i=0;i<N;i++){
if(numbers[i]!= numbers[N-1-i]){
sym=false;}
}
if(sym==true){
System.out.println("The array is a symetrical array");
}
else{
System.out.println("The array is NOT a symetrical array");
}
}
}
This check is useless:
if((i == n-1-i) && (A[i] == A[n-1-i] ))
return true;
Of course if the two indices are the same the values there will match.
Also you need to split this if in two:
if(A[i] == A[n-1-i] && i < n/2 )
return symmHelper(A, n, i+1);
And return true if i >= n/2.
Otherwise what happens is that after i > n/2 (which means you already know your array is symmetrical), you do not go into that if and thus return false, which is wrong.
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int N;
int i;
N=input.nextInt();
int [] numbers = new int [N];
for (i=0; i<N; i++){
numbers[i]= input.nextInt();
}
i=0;
while (i<N/2&& numbers[i] == numbers [N-1-i]){i++;
}
if(i==N/2){
System.out.println("The array is a symetrical array");
}
else{
System.out.println("The array is NOT a symetrical array");
}
}
Related
So I have this programming project in which I need to create a program that determines if a number is a perfect square, and if so, write it into a .txt document. This is very easy and effective to do with a for loop, however, the instructions for the assignment say that the program should accomplish this using recursion. This is the iterative statement I came up with:
double division;
for (int i = 0; i < inputs.size(); i++) {
division = (Math.sqrt(inputs.get(i)));
if (division == (int)division) {
pw.println(inputs.get(i));
}
}
Where inputs is an ArrayList that is created by reading the inputs of the user.
This solves the problem, but like I said, it needs to be a recursive statement. I know that for recursion I need a base case that will eventually make the method stop calling itself, but I can't figure out what the base case would be. Also, I've seen several examples of converting from iteration to recursion, but all of these examples use a single int variable, and in my case I need to do it with an ArrayList.
Any help would be greatly appreciated
For recursive function, you can use bynary search algorithm:
int checkPerfectSquare(long N,
long start,
long last)
{
// Find the mid value
// from start and last
long mid = (start + last) / 2;
if (start > last)
{
return -1;
}
// Check if we got the number which
// is square root of the perfect
// square number N
if (mid * mid == N)
{
return (int)mid;
}
// If the square(mid) is greater than N
// it means only lower values then mid
// will be possibly the square root of N
else if (mid * mid > N)
{
return checkPerfectSquare(N, start,
mid - 1);
}
// If the square(mid) is less than N
// it means only higher values then mid
// will be possibly the square root of N
else
{
return checkPerfectSquare(N, mid + 1,
last);
}
}
You could use the fact that a square number is the sum of the odd integers. E.g.
1+3 = 4 = 2^2
1+3+5 = 9 = 3^2
1+3+5+7 = 16 = 4^2, etc
public static void main(String[] args) {
for (int i = 1; i < 1000; i++) {
if (isSquare(i)) System.out.println(i);
}
}
public static boolean isSquare(int n) {
if (n==0 || n==1) return true;
return isSquare(n,1,1);
}
private static boolean isSquare(int n, int sum, int odd) {
if (n==sum) return true;
if (n < sum) return false;
odd += 2;
sum += odd;
return isSquare(n, sum, odd);
}
output:
1
4
9
16
25
36
49
64
81
100
121
144
169
196
225
256
289
324
361
400
441
484
529
576
625
676
729
784
841
900
961
You could recursively check if the square of any smaller int is equal to your input.
public static boolean isSquare(int n) {
if (n==0 || n==1) return true;
return isSquare(n, 1);
}
private static boolean isSquare(int n, int i) {
if (i*i == n) return true;
if (i*i > n) return false;
return isSquare(n,i+1);
}
I am trying to find the Largest prime factor of a number while solving this problem here. I think that I am doing everything right, however one of the test case (#2) is failing and I can't think of any corner case where it might fail. Here's my code, please have a look and try to spot something.
public class ProblemThree
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
int T = scanner.nextInt();
for (int i = 0; i < T; i++)
{
System.out.println(largestPrime(scanner.nextLong()));
}
}
private static long largestPrime(long n)
{
while (n % 2 == 0)
{
n = n / 2; // remove all the multiples of 2
}
while (n % 3 == 0)
{
n = n / 3; // remove all the multiples of 2
}
// remove multiples of prime numbers other than 2 and 3
while (n >= 5)
{
boolean isDivisionComplete = true;
for (long i = 5; i < Math.ceil(Math.sqrt(n)); i++)
{
if (n % i == 0)
{
n = n / i;
isDivisionComplete = false;
break;
}
}
if (isDivisionComplete)
{
break;
}
}
return n;
}
}
Basically, what I am doing is:
Largest_Prime(n):
1. Repeatedly divide the no by any small number, say x where 0 < x < sqrt(n).
2. Then set n = n/x and repeat steps 1 and 2 until there is no such x that divides n.
3 Return n.
It seems you have some bug in your code as as when you input 16 largestPrime function return 1. and this is true for when input is the power of 3.
Detailed Algorithm description:
You can do this by keeping three variables:
The number you are trying to factor (A)
A current divisor store (B)
A largest divisor store (C)
Initially, let (A) be the number you are interested in - in this case, it is 600851475143. Then let (B) be 2. Have a conditional that checks if (A) is divisible by (B). If it is divisible, divide (A) by (B), reset (B) to 2, and go back to checking if (A) is divisible by (B). Else, if (A) is not divisible by (B), increment (B) by +1 and then check if (A) is divisible by (B). Run the loop until (A) is 1. The (3) you return will be the largest prime divisor of 600851475143.
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(int a0 = 0; a0 < t; a0++){
long n = in.nextLong();
long A=n;
long B=2;
long C=0;
while(Math.pow(B,2)<=A)
{
if(A%B==0)
{
C=B;
A=A/B;
B=2;
}
else
B++;
}
if(A>=C)
C=A;
if(A==1)
{ C=2;
break;
}
System.out.println(C);
}
}
Why are you removing multiples of 2 and multiples of 3? This way if you have a number that is any combination of powers of 2 and 3 you will get your answer as 1 which is clearly wrong.
For this problem you can do the naive way of looping from 2 to sqrt(n) and store the largest number which divides n, when you finish your loop just return the highest divisor you found.
1 drop your loop for 2 and 3. If not, you dont get 2, 2x2, 3, 2x3, ... all multiples of 2 and 3
2 change your loop to stop at 2 (and not 5):
while (n >= 2)
{
3 stop if 2
if (n==2) return 2;
4 loop from 2
and
5 loop until sqrt(n), with <= and not only < (if not, you dont get prime X Prime)
for (long i = 2; i <= Math.ceil(Math.sqrt(n)); i++)
One easy way of extracting prime factors is like this:
/**
* Prime factors of the number - not the most efficient but it works.
*
* #param n - The number to factorise.
* #param unique - Want only unique factors.
* #return - List of all prime factors of n.
*/
public static List<Long> primeFactors(long n, boolean unique) {
Collection<Long> factors;
if (unique) {
factors = new HashSet<>();
} else {
factors = new ArrayList<>();
}
for (long i = 2; i <= n / i; i++) {
while (n % i == 0) {
factors.add(i);
n /= i;
}
}
if (n > 1) {
factors.add(n);
}
return new ArrayList<>(factors);
}
Those first loops are a problem. They will reduce all even numbers to 1 - thus missing 2 as the factor. Changing your code to use:
while (n > 2 && n % 2 == 0) {
n = n / 2; // remove all the multiples of 2
}
while (n > 3 && n % 3 == 0) {
n = n / 3; // remove all the multiples of 2
}
You still have further issues - e.g. you report the largest prime factor of 25 to be 25 and the largest prime factor of 49 to be 49.
Just run this code using yours and mine to see where yours fails:
for (long i = 1; i < 1000; i++) {
long largestPrime = largestPrime(i);
List<Long> primeFactors = primeFactors(i, true);
if (primeFactors.size() > 0) {
Collections.sort(primeFactors, Collections.reverseOrder());
long highestFactor = primeFactors.get(0);
if (largestPrime != highestFactor) {
System.out.println("Wrong! " + i + " " + largestPrime + " != " + primeFactors);
}
} else {
System.out.println("No factors for " + i);
}
}
This question is poorly worded, but how do I make my code run as desired without getting about a hundred error messages at run time when I use recursion? This is my faulty program
public class Collatz
{
public static int count;
public static int pluscount() {
return count++;
}
public static void collatz (int n)
{
if (n < count) {
System.out.print(n + "");
}
if (n == 1) return;
if (n % 2 == 0) {
pluscount();
collatz(n / 2);
}
else {
pluscount();
collatz(3*n + 1);
}
}
public static void main(String[] args)
{
int N = Integer.parseInt(args[0]);
int[] array = new int [N+1];
for (int i = 0; i <= N; i++) {
count = 0;
collatz(i);
array [i] = count;
}
int max = StdStats.max(array);
System.out.println(max);
}
}
If I change the collatz() method to
public static void collatz (int n)
{
count ++;
StdOut.print(n + "");
if (n == 1 || n == 0) return;
if (n % 2 == 0) collatz(n / 2);
else
collatz(3*n + 1);
}
and remove the pluscount() from my code, and input 7 as the argument, the code runs and prints 01213105168421421516842163105168421722113417522613402010516842117
175226134020105168421, but it's supposed to print 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
Here are the instructions from my Java textbook if anyone doesn't understand what I'm trying to accomplish:
Consider the following recursive function, which is related to a famous unsolved problem in number theory, known as the Collatz problem or the 3n + 1 problem.
public static void collatz(int n) {
System.out.print(n + " ");
if (n == 1) return;
if (n % 2 == 0) collatz(n / 2);
else collatz(3*n + 1);
}
For example, a call to collatz(7) prints the sequence
7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
as a consequence of 17 recursive calls. Write a program that takes a command-line argument N and returns the value of n < N for which the number of recursive calls for collatz(n) is maximized.
There are two problem with your code
1.For loop in main method starts with 0 which causes problem.Start iterating from 1
for (int i = 1; i <= N; i++)
2.No need to put if (n < count) in collatz method
When you call collatz(i) and get the result, I would not save it to an array. Instead just keep track of you max count and your max n. Something like this should do the trick based on the approach you are going:
public static int count;
public static void collatz(int n) {
count++;
//System.out.print(n + " ");
if (n == 1) return;
if (n % 2 == 0) collatz(n / 2);
else collatz(3*n + 1);
}
public static void main(String[] args)
{
int N = Integer.parseInt(args[0]);
int maxn = 0;
int maxCount = 0;
for (int i=1; i<=N; i++){ //Start at 1 since collatz(0) is infinite
count = 0;
collatz(i);
if (count>maxCount){
maxCount = count;
maxn = i;
}
}
System.out.println("your max n is: "+maxn);
}
Also notice that I commented out the print statment in collatz. The problem just focuses on how many recursion calls are being made. We do not really care what the output is during all of the recursion calls.
Hope this helps.
Here is my program for outputting prime factorization of a given number. I am still just a beginner in java so I know it is not the most efficient code. The problem arises when I input relatively big numbers.
Input: 11 Output: 11
Input: 40 Output: 2 2 2 5
Input: 5427 Output: 3 3 3 3 67
Input: 435843 Output: 3 3 79 613
Input: 23456789 Output: none (there appears to be an infinite loop and the code should return 23456789 since it is a prime number on its own)
What might cause this issue?
import java.util.Scanner;
public class PrimeFactorization {
public static boolean isPrime(long n) {
boolean boo = false;
long counter = 0;
if (n == 1) {
boo = false;
} else if (n == 2) {
boo = true;
} else {
for (long i = 2; i < n; i++) {
if (n % i == 0) {
counter++;
}
}
if (counter == 0) {
boo = true;
}
}
return boo;
}
public static void primeFactorization(long num) {
for (long j = 1; j <= num; j++) {
if (isPrime(j)) {
if (num % j == 0) {
while (num % j == 0) {
System.out.printf(j + " ");
num = num / j;
}
}
}
if (num == 1) {
break;
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter any number:");
long num = scanner.nextLong();
System.out.print("Prime factorization of your number is: ");
primeFactorization(num);
scanner.close();
}
}
There's no actual error - you're just doing things a very inefficient way. Basically, you're checking every number between 1 and 23456789 for primeness, before dividing.
There's absolutely no point in doing this check. As you work your way up from 1 to 23456789, each time you uncover a factor, you know it has to be prime, because you've already divided out all smaller factors. So if you do all of the following, this will still work correctly, and much more quickly.
Remove the isPrime method completely.
Remove the line if (isPrime(j)) {, and the matching }
Change the loop so that j starts at 2, like for(long j = 2 ; j <= num ; j++) {
Remove if (num == 1) { break; } from the end of the loop. It serves no purpose at all.
No matter how efficient the code, factorizing large numbers takes a while - so long it may feel like the computer has hung. Given your code, even modestly large numbers will take a long time.
The main thing you can do to improve your code's efficiency to to note that for any pair of factors of a number, one of them will be no more than the square root of the number. You can use this fact to limit the loop to reduce the order of you algorithm for O(n) to O(log n).
long sqrt = Math.sqrt(number);
for (long i = 2; i < sqrt; i++) {
...
There are many other things you can do, but this change will have the greatest effect.
If number changes value during the loop (as for example in your second factorizing loop), you'll if course need to recalculate the end value:
for (...)
// if number changes
sqrt = Math.sqrt(number);
I am working on a prime factorization program implemented in Java.
The goal is to find the largest prime factor of 600851475143 (Project Euler problem 3).
I think I have most of it done, but I am getting a few errors.
Also my logic seems to be off, in particular the method that I have set up for checking to see if a number is prime.
public class PrimeFactor {
public static void main(String[] args) {
int count = 0;
for (int i = 0; i < Math.sqrt(600851475143L); i++) {
if (Prime(i) && i % Math.sqrt(600851475143L) == 0) {
count = i;
System.out.println(count);
}
}
}
public static boolean Prime(int n) {
boolean isPrime = false;
// A number is prime iff it is divisible by 1 and itself only
if (n % n == 0 && n % 1 == 0) {
isPrime = true;
}
return isPrime;
}
}
Edit
public class PrimeFactor {
public static void main(String[] args) {
for (int i = 2; i <= 600851475143L; i++) {
if (isPrime(i) == true) {
System.out.println(i);
}
}
}
public static boolean isPrime(int number) {
if (number == 1) return false;
if (number == 2) return true;
if (number % 2 == 0) return false;
for (int i = 3; i <= number; i++) {
if (number % i == 0) return false;
}
return true;
}
}
Why make it so complicated? You don't need do anything like isPrime(). Divide it's least divisor(prime) and do the loop from this prime. Here is my simple code :
public class PrimeFactor {
public static int largestPrimeFactor(long number) {
int i;
for (i = 2; i <= number; i++) {
if (number % i == 0) {
number /= i;
i--;
}
}
return i;
}
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(largestPrimeFactor(13195));
System.out.println(largestPrimeFactor(600851475143L));
}
}
edit: I hope this doesn't sound incredibly condescending as an answer. I just really wanted to illustrate that from the computer's point of view, you have to check all possible numbers that could be factors of X to make sure it's prime. Computers don't know that it's composite just by looking at it, so you have to iterate
Example: Is X a prime number?
For the case where X = 67:
How do you check this?
I divide it by 2... it has a remainder of 1 (this also tells us that 67 is an odd number)
I divide it by 3... it has a remainder of 1
I divide it by 4... it has a remainder of 3
I divide it by 5... it has a remainder of 2
I divide it by 6... it has a remainder of 1
In fact, you will only get a remainder of 0 if the number is not prime.
Do you have to check every single number less than X to make sure it's prime? Nope. Not anymore, thanks to math (!)
Let's look at a smaller number, like 16.
16 is not prime.
why? because
2*8 = 16
4*4 = 16
So 16 is divisible evenly by more than just 1 and itself. (Although "1" is technically not a prime number, but that's technicalities, and I digress)
So we divide 16 by 1... of course this works, this works for every number
Divide 16 by 2... we get a remainder of 0 (8*2)
Divide 16 by 3... we get a remainder of 1
Divide 16 by 4... we get a remainder of 0 (4*4)
Divide 16 by 5... we get a remainder of 1
Divide 16 by 6... we get a remainder of 4
Divide 16 by 7... we get a remainder of 2
Divide 16 by 8... we get a remainder of 0 (8*2)
We really only need one remainder of 0 to tell us it's composite (the opposite of "prime" is "composite").
Checking if 16 is divisible by 2 is the same thing as checking if it's divisible by 8, because 2 and 8 multiply to give you 16.
We only need to check a portion of the spectrum (from 2 up to the square-root of X) because the largest number that we can multiply is sqrt(X), otherwise we are using the smaller numbers to get redundant answers.
Is 17 prime?
17 % 2 = 1
17 % 3 = 2
17 % 4 = 1 <--| approximately the square root of 17 [4.123...]
17 % 5 = 2 <--|
17 % 6 = 5
17 % 7 = 3
The results after sqrt(X), like 17 % 7 and so on, are redundant because they must necessarily multiply with something smaller than the sqrt(X) to yield X.
That is,
A * B = X
if A and B are both greater than sqrt(X) then
A*B will yield a number that is greater than X.
Thus, one of either A or B must be smaller than sqrt(X), and it is redundant to check both of these values since you only need to know if one of them divides X evenly (the even division gives you the other value as an answer)
I hope that helps.
edit: There are more sophisticated methods of checking primality and Java has a built-in "this number is probably prime" or "this number is definitely composite" method in the BigInteger class as I recently learned via another SO answer :]
You need to do some research on algorithms for factorizing large numbers; this wikipedia page looks like a good place to start. In the first paragraph, it states:
When the numbers are very large, no efficient integer factorization algorithm is publicly known ...
but it does list a number of special and general purpose algorithms. You need to pick one that will work well enough to deal with 12 decimal digit numbers. These numbers are too large for the most naive approach to work, but small enough that (for example) an approach based on enumerating the prime numbers starting from 2 would work. (Hint - start with the Sieve of Erasthones)
Here is very elegant answer - which uses brute force (not some fancy algorithm) but in a smart way - by lowering the limit as we find primes and devide composite by those primes...
It also prints only the primes - and just the primes, and if one prime is more then once in the product - it will print it as many times as that prime is in the product.
public class Factorization {
public static void main(String[] args) {
long composite = 600851475143L;
int limit = (int)Math.sqrt(composite)+1;
for (int i=3; i<limit; i+=2)
{
if (composite%i==0)
{
System.out.println(i);
composite = composite/i;
limit = (int)Math.sqrt(composite)+1;
i-=2; //this is so it could check same prime again
}
}
System.out.println(composite);
}
}
You want to iterate from 2 -> n-1 and make sure that n % i != 0. That's the most naive way to check for primality. As explained above, this is very very slow if the number is large.
To find factors, you want something like:
long limit = sqrt(number);
for (long i=3; i<limit; i+=2)
if (number % i == 0)
print "factor = " , i;
In this case, the factors are all small enough (<7000) that finding them should take well under a second, even with naive code like this. Also note that this particular number has other, smaller, prime factors. For a brute force search like this, you can save a little work by dividing out the smaller factors as you find them, and then do a prime factorization of the smaller number that results. This has the advantage of only giving prime factors. Otherwise, you'll also get composite factors (e.g., this number has four prime factors, so the first method will print out not only the prime factors, but the products of various combinations of those prime factors).
If you want to optimize that a bit, you can use the sieve of Eratosthenes to find the prime numbers up to the square root, and then only attempt division by primes. In this case, the square root is ~775'000, and you only need one bit per number to signify whether it's prime. You also (normally) only want to store odd numbers (since you know immediately that all even numbers but two are composite), so you need ~775'000/2 bits = ~47 Kilobytes.
In this case, that has little real payoff though -- even a completely naive algorithm will appear to produce results instantly.
I think you're confused because there is no iff [if-and-only-if] operator.
Going to the square root of the integer in question is a good shortcut. All that remains is checking if the number within that loop divides evenly. That's simply [big number] % i == 0. There is no reason for your Prime function.
Since you are looking for the largest divisor, another trick would be to start from the highest integer less than the square root and go i--.
Like others have said, ultimately, this is brutally slow.
private static boolean isPrime(int k) throws IllegalArgumentException
{
int j;
if (k < 2) throw new IllegalArgumentException("All prime numbers are greater than 1.");
else {
for (j = 2; j < k; j++) {
if (k % j == 0) return false;
}
}
return true;
}
public static void primeFactorsOf(int n) {
boolean found = false;
if (isPrime(n) == true) System.out.print(n + " ");
else {
int i = 2;
while (found == false) {
if ((n % i == 0) && (isPrime(i))) {
System.out.print(i + ", ");
found = true;
} else i++;
}
primeFactorsOf(n / i);
}
}
For those answers which use a method isPrime(int) : boolean, there is a faster algorithm than the one previously implemented (which is something like)
private static boolean isPrime(long n) { //when n >= 2
for (int k = 2; k < n; k++)
if (n % k == 0) return false;
return true;
}
and it is this:
private static boolean isPrime(long n) { //when n >= 2
if (n == 2 || n == 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int k = 1; k <= (Math.floor(Math.sqrt(n)) + 1) / 6; k++)
if (n % (6 * k + 1) == 0 || n % (6 * k - 1) == 0) return false;
return true;
}
I made this algorithm using two facts:
We only need to check for n % k == 0 up to k <= Math.sqrt(n). This is true because for anything higher, factors merely "flip" ex. consider the case n = 15, where 3 * 5 = 5 * 3, and 5 > Math.sqrt(15). There is no need for this overlap of checking both 15 % 3 == 0 and 15 % 5 == 0, when we could just check one of these expressions.
All primes (excluding 2 and 3) can be expressed in the form (6 * k) + 1 or (6 * k) - 1, because any positive integer can be expressed in the form (6 * k) + n, where n = -1, 0, 1, 2, 3, or 4 and k is an integer <= 0, and the cases where n = 0, 2, 3, and 4 are all reducible.
Therefore, n is prime if it is not divisible by 2, 3, or some integer of the form 6k ± 1 <= Math.sqrt(n). Hence the above algorithm.
--
Wikipedia article on testing for primality
--
Edit: Thought I might as well post my full solution (*I did not use isPrime(), and my solution is nearly identical to the top answer, but I thought I should answer the actual question):
public class Euler3 {
public static void main(String[] args) {
long[] nums = {13195, 600851475143L};
for (num : nums)
System.out.println("Largest prime factor of " + num + ": " + lpf(num));
}
private static lpf(long n) {
long largestPrimeFactor = 1;
long maxPossibleFactor = n / 2;
for (long i = 2; i <= maxPossibleFactor; i++)
if (n % i == 0) {
n /= i;
largestPrimeFactor = i;
i--;
}
return largestPrimeFactor;
}
}
To find all prime factorization
import java.math.BigInteger;
import java.util.Scanner;
public class BigIntegerTest {
public static void main(String[] args) {
BigInteger myBigInteger = new BigInteger("65328734260653234260");//653234254
BigInteger originalBigInteger;
BigInteger oneAddedOriginalBigInteger;
originalBigInteger=myBigInteger;
oneAddedOriginalBigInteger=originalBigInteger.add(BigInteger.ONE);
BigInteger index;
BigInteger countBig;
for (index=new BigInteger("2"); index.compareTo(myBigInteger.add(BigInteger.ONE)) <0; index = index.add(BigInteger.ONE)){
countBig=BigInteger.ZERO;
while(myBigInteger.remainder(index) == BigInteger.ZERO ){
myBigInteger=myBigInteger.divide(index);
countBig=countBig.add(BigInteger.ONE);
}
if(countBig.equals(BigInteger.ZERO)) continue;
System.out.println(index+ "**" + countBig);
}
System.out.println("Program is ended!");
}
}
I got a very similar problem for my programming class. In my class it had to calculate for an inputted number. I used a solution very similar to Stijak. I edited my code to do the number from this problem instead of using an input.
Some differences from Stijak's code are these:
I considered even numbers in my code.
My code only prints the largest prime factor, not all factors.
I don't recalculate the factorLimit until I have divided all instances of the current factor off.
I had all the variables declared as long because I wanted the flexibility of using it for very large values of number. I found the worst case scenario was a very large prime number like 9223372036854775783, or a very large number with a prime number square root like 9223371994482243049. The more factors a number has the faster the algorithm runs. Therefore, the best case scenario would be numbers like 4611686018427387904 (2^62) or 6917529027641081856 (3*2^61) because both have 62 factors.
public class LargestPrimeFactor
{
public static void main (String[] args){
long number=600851475143L, factoredNumber=number, factor, factorLimit, maxPrimeFactor;
while(factoredNumber%2==0)
factoredNumber/=2;
factorLimit=(long)Math.sqrt(factoredNumber);
for(factor=3;factor<=factorLimit;factor+=2){
if(factoredNumber%factor==0){
do factoredNumber/=factor;
while(factoredNumber%factor==0);
factorLimit=(long)Math.sqrt(factoredNumber);
}
}
if(factoredNumber==1)
if(factor==3)
maxPrimeFactor=2;
else
maxPrimeFactor=factor-2;
else
maxPrimeFactor=factoredNumber;
if(maxPrimeFactor==number)
System.out.println("Number is prime.");
else
System.out.println("The largest prime factor is "+maxPrimeFactor);
}
}
public class Prime
{
int i;
public Prime( )
{
i = 2;
}
public boolean isPrime( int test )
{
int k;
if( test < 2 )
return false;
else if( test == 2 )
return true;
else if( ( test > 2 ) && ( test % 2 == 0 ) )
return false;
else
{
for( k = 3; k < ( test/2 ); k += 2 )
{
if( test % k == 0 )
return false;
}
}
return true;
}
public void primeFactors( int factorize )
{
if( isPrime( factorize ) )
{
System.out.println( factorize );
i = 2;
}
else
{
if( isPrime( i ) && ( factorize % i == 0 ) )
{
System.out.print( i+", " );
primeFactors( factorize / i );
}
else
{
i++;
primeFactors( factorize );
}
}
public static void main( String[ ] args )
{
Prime p = new Prime( );
p.primeFactors( 649 );
p.primeFactors( 144 );
p.primeFactors( 1001 );
}
}