is there a more efficient, cleaner/elegant way of finding prime numbers than this? The code works fine, but I just wrote what seemed most logical to me and I can't figure out any other way, but to be honest it just doesn't look nice :P. I know coding isn't the most elegant of activities.
Here's my main method:
import java.util.Scanner;
public class DisplayPrimeNumbers
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.print("Enter an integer that you'd like the system to print the prime numbers till: ");
String input1 = scan.nextLine();
int input = Integer.parseInt(input1);
PrimeGenerator prime = new PrimeGenerator(input);
for (int i = 1; i < input ; i++)
{
if(prime.isPrime())
{
System.out.println(prime.getNextPrime());
}
}
System.out.println(1);
}
}
Here's my class:
public class PrimeGenerator
{
private int number;
public PrimeGenerator(int n)
{
number = n;
}
public int getNextPrime ()
{
return number+1;
}
public boolean isPrime()
{
for(int i = 2; i < number; i++)
{
if (number % i == 0)
{
number--;
return false;
}
}
number--;
return true;
}
}
While this question has already been answered I figured I'd provide my answer anyway in the hopes that somebody may find it useful:
You seem to be primarily concerned with 2 both elegance and efficiency. I'd also like to point out that correctness is equally important. Unless you have a special requirement to treat the number 1 as prime it is no longer considered so. You should equally consider the scenario when the user enters a prime number. You should also give some thought into the boundry condition of what numbers you print. Specifically if I enter the number 7, will your users expect it to output 5,3,2,1 or 7,5,3,2,1. While my personal tendency would be towards the latter, using clear and concise messages can make either option work.
Elegance
The perceived lack of elegance in your solution is largely due to your combination of two concepts: Prime Number Testing and Prime Number Generation.
A Prime Number Test is a (quick) method to determine whether or not a single arbitrarily chosen number is prime.
A Prime Number Generator is a way of generating a sequence of prime numbers which are often consecutive.
As your program demonstrates you can generate a consecutive sequence of prime numbers by testing each number within a given range and only selecting those which are prime! Keeping this as our basic strategy for the moment, let's figure out what the code might:
From our description earlier we said that a prime number test was a method (aka function) to determine if some arbitrarily chosen number was prime. So this method should take as input a(n arbitrarily chosen) number and return wether or not the given numbe was prime (ie: true/false). Let's see how it looks:
public interface PrimeNumberTest
{
bool isPrime(int value);
}
And incorporating your prime number test
public class BruteForcePrimeNumberTester : PrimeNumberTest
{
public bool isPrime(int value)
{
bool isPrime = true;
for(int i = 2; isPrime && i < value; i++)
{
if (value % i == 0)
{
isPrime = false;
}
}
return isPrime;
}
}
Your main program is then responsible for iterating over each number and printing only thsoe which the prime number test identifies as prime.
public static void main(String[] args)
{
//Determine the range of prime numbers to print
Scanner scan = new Scanner(System.in);
System.out.print("Primes smaller than what number should be printed?: ");
int max = Integer.parseInt(scan.nextLine());
//Identify how prime numbers will be tested
PrimeNumberTest test = new BruteForcePrimeNumberTest();
//Uncomment the line below if you want to include the number 1. Favour adding it here so that you may
//use re-use your prime number test elsewhere that atually needs to know if a number is prime.
//System.out.println(1);
//Print the prime numbers
for (int i = 2; i < max ; i++)
{
if(test.isPrime(i))
{
System.out.println(i);
}
}
}
Your main program however should only be concerned with prime number generation. It doesn't really care about the semantics of how those primes are generated we just want the primes. It doesn't really matter if the primes were found via primality testing or any other algorithm. So we ask ourselves what does a prime number generator look like?
For starter primes are always whole numbers so we shouldn't be storing them inside floats, doubles or decimals. That leaves 32 and 64 bit integers. If you want to generate larger prime numbers then obviously you should use the long type but I'm just going to use int. In other languages we would also have to consider things like unsigned numbers too.
Now we need to find a way to return all of these numbers at once. Trees don't really make sense as we're going to be generating a consecutive sequence. Stacks don't make sense because consumers typically want the numbers in the order they were generated. Queues could be used as they fit the first-in-first-out rule. In fact if the end application had an asynchronous prime number generator (producer) and a separate asynchronous consumer this type would be ideal. For this example however I want something read-only. Essentially a prime number generator is an Iterable<int>.
public class PrimeNumberTestGenerator : Iterable<int>
{
private int limit;
private PrimalityTester tester;
public PrimeNumberTestGenerator(PrimalityTester tester, int limit)
{
this.tester = tester;
this.limit = limit;
}
private class PrimeNumberIterator : Iterator<int>
{
private int current;
public PrimeNumberIterator()
{
}
public bool hasNext()
{
return next < limit;
}
public int moveNext()
{
if (!hasNext())
{
throw new NoSuchElementException();
}
int result = next;
do
{
next++;
} while(hasNext() && !tester.isPrime(next));
return result;
}
public void remove()
{
throw new UnsupportedOperationExecution();
}
}
public Iterator<int> iterator()
{
return new PrimeNumberIterator();
}
}
So how do we tie them together?
public static void main(String[] args)
{
//Determine the range of prime numbers to print
Scanner scan = new Scanner(System.in);
System.out.print("Primes smaller than what number should be printed?: ");
int max = Integer.parseInt(scan.nextLine());
//Identify how prime numbers will be tested
Iterable<int> primes = new PrimeNumberTestGenerator(max, new BruteForcePrimeNumberTest());
//Print the prime numbers
foreach (int prime : primes)
{
System.out.println(prime);
}
}
Efficiency
Now the other side of your question was an efficient way of determining the prime numbers within a specified range. While a quick internet search should yield a number of different "fast" algorithms for determing a set of prime numbers that are much faste than the brute force way. One such approach is the Sieve of Atkin:
public class AtkinSieve : Iterable<int>
{
private BitSet primes;
public AtkinSieve(int limit)
{
primes = new BitSet(limit);
int root = (int)Math.sqrt(limit);
primes.set(2);
primes.set(3);
//this section can be further optimized but is the approach used by most samples
for (int x = 1; x <= root; x++)
{
for (int y = 1; y <= root; y++)
{
int number;
int remainder;
number = (4 * x * x) + (y * y);
remainder = number % 12;
if (number < limit && (remainder == 1 || remainder == 5))
{
primes.flip(number);
}
number = (3 * x * x) + (y * y);
remainder = number % 12;
if (number < limit && remainder == 7)
{
primes.flip(number);
}
if (x < y)
{
number = (3 * x * x) - (y * y);
remainder = number % 12;
if (number < limit && remainder == 11)
{
primes.flip(number);
}
}
}
}
for (int i = 5; i <= root; i++)
{
if (primes.get(i))
{
int square = i * i;
for (int j = square; j < limit; j += square)
{
primes.clear(j);
}
}
}
}
}
public class SetBitIterator : Iterator<int>
{
private BitSet bits;
private int next;
private bool isReadOnly;
public SetBitIterator(BitSet bits)
{
this.bits = bits;
next = bits.nextSetBit(0);
}
public bool hasNext()
{
return next <> -1;
}
public int moveNext()
{
int result = next;
next = bits.nextSetBit(next);
return result;
}
public void remove()
{
throw new UnsupportedOperationException();
}
}
Conveniently we can now use this prime number generator by only changing a single line in our previous main program!
Change:
//Identify how prime numbers will be tested
Iterable<int> primes = new PrimeNumberTestGenerator(max, new BruteForcePrimeNumberTest());
To:
//Identify how prime numbers will be tested
Iterable<int> primes = new AtkinSieve(max);
You can speed up your search for new primes by storing the primes that you have already found in a private collection inside the PrimeGenerator. By trying only them as potential divisors instead of your for(int i = 2; i < number; i++) loop, you will have to do much fewer divisions
You can stop the "find divisors" loop well before you reach the number: specifically, you can stop when your candidate divisor exceeds the square root of the target number. This works, because you try the candidate divisors in ascending order: if there were divisors above the square root, the result of the division would have been below the square root, so you would have already found them.
Your getNextPrime method should call isPrime internally before returning the value to the caller. Otherwise, the call of getNextPrime cannot be said to return the next prime.
First and most important thing is.... U need not to check till
i
for(int i = 2; i < number; i++)
U need to to check only untill i is less than number/2...
for(int i = 2; i < (number/2); i++)
This is how I might have written it for simplicity
public static void main(String... args) {
System.out.print("Enter an integer that you'd like the system to print the prime numbers till: ");
Scanner scan = new Scanner(System.in);
int input = scan.nextInt();
if (input >= 2)
System.out.println(2);
OUTER: for (int i = 3; i <= input; i += 2) { // skip every even number
for (int j = 3; j * j <= i; j += 2) // stop when j <= sqrt(i)
if (i % j == 0)
continue OUTER;
System.out.println(i); // 99+% of the time will be spent here. ;)
}
}
Yeah there are. I don´t know if it´s the most efficient, but it is way more efficient then this one. Check the Miller Rabin test.
Even so, if you want to work with your Code, i could tell you, you should do it like this:
public boolean isPrime(int number)
{
// You should know, that every straight number can not be prime,so you can say i+= 2
if (number == 2)
return true;
if (number % 2 == 0)
{
return false;
}
for(int i = 3; i < number; i+=2)
{
if (number % i == 0)
{
number--;
return false;
}
--number;
return true;
}
Why would a PrimeGenerator produce numbers that are not prime? That's not elegant. Remove the isPrime()-method and rewrite the getNextPrime()-method so that it will always return a prime number.
As an improvement you can step by 6 not by 2 and do 2 checks in each step. See what I found here.
Basically, every number can be written as (6k, 6k + 1, 6k+2, 6k+3,
6k+4, or 6k+5). 6k is clearly not prime. Items 6k+2 to 6k+4 can be
written as 2(3k + 1), 3(2k+1), and 2(3k + 2) and therefore aren’t
prime as they’re divisible by 2 or 3.
So my point is the following. If we want to find numbers up to 1000 we can do the following thing.
int [] primes = new int[1000];
primes[0] = 2;
primes[1] = 3;
primes[2] = 5;
primes[3] = 7;
index = 4;
for(int i = 12; i < 1000; i += 6) {
boolean prime1 = true;
boolean prime2 = true;
int j = 1; // No need to divide by 2, the number is odd.
while(j < index && (prime1 || prime2)) {
if (prime1 && ((i - 1) % primes[j] == 0)) {
prime1 = false;
}
if (prime2 && ((i + 1) % primes[j] == 0)) {
prime2 = false;
}
j++;
}
if (prime1) {
primes[index++] = i - 1;
}
if (prime2) {
primes[index++] = i + 1;
}
}
Try this code mate.I wrote this. This is more elegant i think :)
**import java.util.*;
public class PrimeNum{
public static void main(String args[]){
Scanner x=new Scanner(System.in);
System.out.println("Enter the number : ");
long y=x.nextLong();
long i;
for( i=2;i<y;i++){
long z=y%i;
if(z==0){
System.out.println(y+" is not a prime");
System.out.println(y+" Divide by "+i);
i=y;
}
}if(i==y) System.out.println("Number is prime");
if(y==1) System.out.println("Number 1 is not a prime");
}
}**
Based on my observations a basic approach would be to use this:
int prime(int up_limit){
int counter =0;
for(int i=1;i<=up_limit;i++)
{
if(up_limit%i==0)
counter++;
}
if(count==2){
return up_limit;
}
Related
I'm currently doing problem 3 from Project Euler. This the problem I need to solve:
What is the largest prime factor of the number 600851475143 ?
My code compiles as expected when I enter smaller numbers such as 10,000. But when I enter the number from the problem: 600851475143, nothing happens. Here is my code:
import java.util.ArrayList;
class problem3{
public static void main(String args[]){
ArrayList<Long> rr = findFactors(600851475143L);// rr holds an Array of factors.
rr = largestPrime(rr); // rr now holds an Array of factors that are prime.
int sizeOfrr = rr.size();
long largestPrimeFactor = rr.get(sizeOfrr-1);// prints the last(largest) prime factor
System.out.println(largestPrimeFactor);
/*This loops through all of the prime factors found
for(int i = 0; i<rr.size(); i++){
System.out.println(rr.get(i));
}*/
System.exit(0);
}
// This method returns an array of factors of the Long argument passed into parameter number.
public static ArrayList<Long> findFactors(Long number){
ArrayList<Long> factors = new ArrayList<Long>();
for(Long i= 1L; i<=number; i++){ // Divide number by every single digit upto and including itself
// Remember, we need to place L or l after an integer to let the compiler know its a long - not an int primitve.
if(number%i == 0){ // If number modules i is equal to zero, then i is a factor.
factors.add(i); // Append i to the factors array.
}
}
return factors;
}
// Increments the unit divisor, starting at 2L
/* The goal is to find if primeArray[i] has more than one factor. (Exluding 1 itself)
The loop begins at 2L. If primeArray[i]%j == 0, counter will increment by one.
The moment counter hits 2, we know primeArray[i] is not a prime since if it were prime,
the counter would be set to 1 and only 1 (because counter would only increment when j is
equal to primeArray[i] or in otherwords, when it is equal to itself. )
The method below returns an array of all the prime numbers
*/
public static ArrayList<Long> largestPrime(ArrayList<Long> primeArray){
int counter =0;
for(int i = 0; i<primeArray.size(); i++){ // Loops through the prime array
for(Long j = 2L; j<= primeArray.get(i); j++){
// (iL)??; jL++) { // 2L/3 for instance
if(primeArray.get(i)%j == 0){// Is it a factor?
counter++;
}
if(counter > 1){
primeArray.remove(i);
counter = 0;
break;
}
if(j == primeArray.get(i)){
counter = 0;
}
}
}
return primeArray;
}
}
nothing happens
As Qbrute said, you're looping 600851475143 times. It takes really a lot.
Since you have to find the largest prime factor, you don't need to find every factor, so you could skip every even number.
You could find first every prime factor and few others, then keep only the prime ones just comparing the ones you found each other.
Moreover the first loop can end at Math.sqrt(input). What about the (prime) factors above that? Just do input/factor.
Lastly you can keep your array sorted, this way you can stop looking for a prime after the first one. You should also use the primitive every time you can.
These optimization should be enough.
Try this:
public static void main(final String[] args) {
final long n = 600851475143L;
final long largestPrime = findLargestPrimeFactors(n);
System.out.println("The largest prime of " + n + " is: " + largestPrime);
}
public static long findLargestPrimeFactors(final long num) {
final List<Long> factors = new ArrayList<>();
int index = 0;
if ((num % 2L) == 0) {
factors.add(num / 2L);
factors.add(2L);
index = 1;
}
final long end = Double.valueOf(Math.floor(Math.sqrt(num))).longValue();
for (long i = 3L; i <= end; i += 2) { // skip every even number
if ((num % i) == 0) {
// This way the list is sorted in descending order
factors.add(index++, (num / i));
factors.add(index, i);
}
}
final long largestPrime = retainsLargestPrime(factors);
return largestPrime != 1L ? largestPrime : num; // if largestPrime is 1 it means that num is a prime number
}
private static long retainsLargestPrime(final List<Long> factors) {
long largestPrime = 1L;
if ((factors != null) && !factors.isEmpty()) {
final int size = factors.size();
for (int i = 0; (i < size) && (largestPrime == 1L); i++) {
boolean isPrime = true;
final long l = factors.get(i);
for (int j = i + 1; (j < size) && isPrime; j++) {
isPrime = !((l % factors.get(j)) == 0); // stop the inner loop as soon as possible
}
if (isPrime) {
largestPrime = l;
}
}
}
return largestPrime;
}
I wrote the following program for the second problem of project Euler, for the question: "Project Euler #3: Largest prime factor".It is supposed to print out all the highest prime factors of the provided inputs.
import java.util.Scanner;
public class euler_2 {
public static boolean isPrime(int n) {
if (n % 2 == 0) return false;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0)
return false;
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
for (int i = 0; i < a; i++) {
int b = sc.nextInt();
for (int j = b; j >= 1; j--) {
boolean aa = isPrime(j);
if (aa == true && b % j == 0) {
b = j;
break;
}
}
System.out.println(b);
}
}
}
What changes can I make to the program to make it execute faster? What would be a better algorithm for this problem?
The problem with your approach is that for every number N, you try each number smaller or equal to N whether it is a prime and after that whether it is a divisor of N.
Obvious improvement is to check whether it is a divisor first and only then whether it is a prime. But most probably this will not help that much.
What you can do instead is just to start checking each number whether it is a divisor of a number. If it is a divisor, divide it. You continue this till sqrt(N).
I have not done anything with java in a long time, but here is Go implementation, which most probably any Java person will be able to transform to Java.
func biggestPrime(n uint64) uint64 {
p, i := uint64(1), uint64(0)
for i = 2; i < uint64(math.Sqrt(float64(n))) + uint64(1); i++ {
for n % i == 0 {
n /= i
p = i
}
}
if n > 1 {
p = n
}
return p
}
Using my algorithm it will take you O(sqrt(N)) to find the biggest prime of a number. In your case it was O(N * sqrt(N))
Attempt to factor the number into 2 factors. Repeat on the largest factor found so far until you find one that can't be factored -- that is the largest prime factor.
There are many different ways you might try to factor the numbers, but since they are only ints, then Fermat's method or even trial division (going down from sqrt(N)) will probably do. See http://mathworld.wolfram.com/FermatsFactorizationMethod.html
See, I have a boolean method that gets the divisors that work by moding the number by a divisor that is checked and determined true by a for loop (not the first one, that just loops the program for a determined amount of input.
I'm not sure if there's some way to take the multiple results of the loop and add them together, but that is what I need to do. right now I'm displaying the results of the loop but that was for debugging, in the end the output will be whether it is abundant (the added divisors are over the number), perfect (the added divisors equal the number) or deficient (the added divisors are less then the number)
This is the code in eclipse:
import java.util.*;
public class PerfectNumber {
/**
* #param args
*/
public static void main(String[] args) {
for(int i = 0; i < 15; i++)
{
Scanner reader = new Scanner(System.in);
int number = 0;
int divisor = 1;
int addnum = 0;
System.out.println("Please input a number to check if it is perfect, abundant, or deficient");
number = reader.nextInt();
for(divisor = 1; divisor < number; divisor++)
{
isDivisor(number, divisor);
if(isDivisor(number, divisor) == true)
{
System.out.println(divisor);
}
}
}
}
static boolean isDivisor(int number, int divisor)
{
if (number % divisor == 0)
return true;
else
return false;
}
}
To answer what seems to be your immediate question for what smells like a homework problem ;)
I'm not sure if there's some way to take the multiple results of the loop and add them together
You can check the return of your function as you're already doing and increment a counter
public boolean isSeven(int x){
return x == 7;
}
public static void main(String[] args){
int sumOfSevens= 0;
int i = 0;
while(i < 10){
if(isSeven(7)){
sumOfSevens = sumOfSevens + 7; // or +=
++i;
}
}
// At this point sumOfSevens = 70;
}
You don't need isDivisor because it is equal to the following expression:
number % divisor == 0
Just sum up divisors:
int numDivSum = 0;
for(divisor = 1; divisor < Math.sqrt(number); divisor++)
{
if(number % divisor == 0)
{
numDivSum += divisor;
}
}
and check is the numDivSum is perfect, abundant, or deficient.
If you want to sum things in a loop you can use some statement like this:
Int sum;
// your for loop start
If ( isDivisor(number, divisor))
sum += divisor;
// end of loop
//here you can do the comparison.
There is no need to compare to true in your if-statement. Also this codesnippet only works, if you have only one statement in the if body. If you need to do multiple things, you have to wrap that whole thing in brackets.
Also your first call to isDivisor is useless, as you are not doing anything with the value you get.
I have the below program where I am trying to find the sum of first 1000 prime numbers. In the code, what's the difference between solution 1, and 2? Why should I not put the count variable outside the if condition? I am obviously not getting the answer I need if I put the variable outside if, but I don't understand why its logically wrong. It could be a simple thing, but I am unable to figure it out. Experts, please help.
Solution 1:
public class SumOfPrimeNumbers {
public static void main(String[] args) {
long result = 0;
int number = 2;
int count = 0;
while (count < 1000) {
if (checkPrime(number) == true) {
result = result + number;
count++;
}
number++;
}
System.out.println("The sum of first 1000 prime numbers is " + result);
}
public static boolean checkPrime(int number) {
for (int i = 2; i < number; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
}
Solution 2:
public class SumOfPrimeNumbers {
public static void main(String[] args) {
long result = 0;
int number = 2;
int count = 0;
while (count < 1000) {
if(checkPrime(number)==true)
{
result = result + number;
}
count++; //The count variable here has been moved to outside the loop.
number++;
}
System.out.println("The sum of first 1000 prime numbers is "+ result);
}
public static boolean checkPrime(int number) {
for (int i = 2; i < number; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
}
You should not check the return value of bool functions for equality to true: this line
if(checkPrime(number)==true)
is equivalent to
if(checkPrime(number))
Finally, the solution where the count is incremented outside of if counts non-primes together with primes, producing an obviously wrong result.
Here are a couple of points "for style" that you should consider:
Checking candidate divisors in checkPrime can stop when the candidate divisor is greater than the square root of the number
You can do much better if you store the primes that you've seen so far, and checking divisibility only by the numbers from the list of primes. When you are looking for the first 1000 primes this would hardly matter, but for larger numbers this could be significant.
The place where you increment count is pretty important. Your first code chunk adds up the first 1000 primes, while the second one adds up all the primes less than 1000.
In your solution 2, count is incremented EVERY time through the loop, regardless of the result of your prime test. So it is not counting primes, but counting iterations through the loop. As a result, you'll check 1,000 consecutive numbers, not consecutive primes (which involves going through a lot more than 1,000 numbers to accumulate).
In addition to what others have pointed out, your check for prime can be made a little more efficient by:
public static boolean checkPrime(int number) {
int s = Math.ceil(Math.sqrt(number));
for (int i = 2; i <= s; i++) {
if ((number % i) == 0) {
return false;
}
}
return true;
}
class eulerThree {
public static void main(String[] args) {
double x = 600851475143d;
for (double z = 2; z*z <= x; z++) {
if (x%z == 0) {
System.out.println(z + "PRIME FACTOR");
}
}
}
}
and the output is:
71.0
839.0
1471.0
6857.0
59569.0
104441.0
486847.0
So, I assume 486847 is the largest prime factor of x, but project euler says otherwise. I don't see a problem in my code or my math, so I'm pretty confused. Can you see anything I can't?
Firstly, you have to use an accurate arithmetic means. Others have suggested using BigInteger. You can do this. To me, it feels a bit like cheating (this will be more important for later problems that deal with much larger integers) so the more fun way (imho) is to write the necessary arbitrary precision operations yourself.
Second, 600851475143 is small enough to be done accurate with a long, which will be much faster.
Third, your loop isn't correctly checking for prime factors. You're just checking odd numbers. This is a barebones (incomplete) solution:
long num = 600851475143L;
List<Long> factors = new ArrayList<Long>(); // or use a Set
if (num & 1 == 0) {
factors.add(2L);
}
for (long i=3; i*i<=num; i+=2) {
// first check i is prime
// if i is prime check if it is a factor of num
}
Checking if something is prime has differing levels of implementation. The most naive:
public boolean isPrime(long num) {
for (long i=2; i<=num; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
Of course that does all sorts of unnecessary checking. As you've already determined you only need to check numbers up to sqrt(n) and you can eliminate even numbers (other than 2):
public boolean isPrime(long num) {
if (num & 1 == 0) {
return false; // checks divisibility by 2
}
for (long i=3; i*i<=num; i+=2) {
if (num % i == 0) {
return false;
}
}
return true;
}
But you can do better than this as well. Another optimization is that you only need to check a number by prime numbers within that range. The prime factors of 63 are 3 and 7. If a number isn't divisible by 3 or 7 then it by definition won't be divisible by 63.
So what you want to do is build up probably a Set<Long> or prime numbers until the square is equal to or higher than your target number. Then just check this series of numbers for divisibility into the target.
double is inherently inaccurate for large values and should never be used for these type of number operations. The right class to use is BigInteger, which allows arbitrarily large integral values to be represented precisely. See this wikipedia article for a description on what floating point data types are and are not.
First, use BigInteger or long rather than double. Double isn't exact, and as you get to later problems, it won't be correct at all.
Second, what you're printing is factors, not prime factors.
This will work in your case:
for (double z = 2; z <= x; z++) {
if (x%z == 0) {
while( x%z == 0)
x = x/z
System.out.println(z + "PRIME FACTOR");
}
}
Also, Project Euler gives you sample input and output. Use that, since your code doesn't output values that match the example they give in the problem.
Two things:
Don't use double, the bigger the numbers the less precision it has. Instead you can use BigInteger to store arbitrarily large integers, or in this case a simple long will suffice.
You need to divide by the prime factor after you find it, otherwise you'll find all factors not just prime factors. Something like this:
if (x % z == 0) {
System.out.println(z + "PRIME FACTOR");
x /= z;
z -= 1; // Might be present multiple times, try it again
}
public class Prime {
public static void main(String[] args) {
double out = 0;
double m = 600851475143d;
for (double n = 3; n < m; n += 2) {
while (m % n == 0) {
out = n;
m = m / n;
}
}
System.out.println("" + ((m == 1)?out:m));
}
}
See the program. And you'll understand the algorithm. This is very easy and very fast. And return the correct answer 6857.
import java.util.Scanner;
class Primefactor
{
public static void main(String args[])
{
Scanner get=new Scanner(System.in);
System.out.println("Enter a number");
long number=get.nextLong();
int count=0;
long input=number;
for(long i=number;i>=1;number--)
{
for(long j=number;j>=1;j--)
{
if(i%j==0)
{
count++;
}
if(count==2)
{
if(input%j==0)
{
System.out.println(j);
}
}
}
}
}
}
This is to see largest primefactor of any number within the datatype limit.
public static void largestPrimeNo(long lim)
{
long newNum = lim;
long largestFact = 0;
int counter = 2;
while( counter * counter <= newNum )
{
if(newNum % counter == 0)
{
newNum = newNum / counter;
largestFact = counter;
}else{
counter++;
}
}
if(newNum > largestFact)
{
largestFact=newNum;
}
System.out.println(largestFact);
}
}
as Prime no is work on the principle that Any integer greater than 1 is either a prime number, or can be written as a unique product of prime numbers.So we can easily use above program.In this program we divide the long no,and find its prime factor
package findlaragestprimefactor;
public class FindLaragestPrimeFactor{
boolean isPrime(long number) {
for (long divider = 2; divider <= number / 2; divider++) {
if (number % divider == 0) {
return false;
}
}
return true;
}
void calculateLargestPrimeFactor() {
long largestPrimeFactor = 0;
long x = 600851475143L;
for(long factor = 3 ; factor <= x/2 ; factor = factor + 2){
if(x%factor==0 & factor>largestPrimeFactor & isPrime(factor)){
largestPrimeFactor = factor;
}
}
System.out.println(largestPrimeFactor);
}
public static void main(String[] args) {
MyProject m = new MyProject();
m.calculateLargestPrimeFactor();
}
}
long tNum=600851475143L;
ArrayList<Integer> primeNum=new ArrayList();
System.out.println(10086647/1471);
for(int i=2;i<=tNum;i++) {
if(tNum%i==0) {
primeNum.add(i);
tNum=tNum/i;
}
}
System.out.println(primeNum);