The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
public class Problem10
{
public static void main(String[] args)
{
int sum = 17;
for(long i=11; i<2000000; i+=2)
{
if(isPrime(i)) sum += i;
}
System.out.println(sum);
}
public static boolean isPrime(long n)
{
if(n==2) return true;
if(n%2 == 0) return false;
for(long i=3; i<= Math.sqrt(n); i+=2)
{
if(n%i == 0) return false;
}
return true;
}
}
I don't see what is wrong with this. It keeps printing 1179908154 which is incorrect.
Your sum is an int, but integer overflow is occurring. If you change the datatype to long, then the answer changes to 142913828922, which is longer than the maximum possible int. That appears to be the correct answer.
Related
I was asked to write a program to find next prime number in an optimal way. I wrote this code, but I could not find an optimal answer to it. Any suggestions?
public static int nextPrime(int input) {
input++;
//now find if the number is prime or not
for(int i=2;i<input;i++) {
if(input % i ==0 ) {
input++;
i=2;
}
else{
continue;
}
}
return input;
}
public int nextPrime(int input){
int counter;
input++;
while(true){
int l = (int) sqrt(input);
counter = 0;
for(int i = 2; i <= l; i ++){
if(input % i == 0) counter++;
}
if(counter == 0)
return input;
else{
input++;
continue;
}
}
}
There is no need to check up on input number. It is enough to check up to the square root of a number. Sorry, I didn't remember the theorem name. Here we are incrementing the input for next prime.
The time complexity of this solution O(n^(3/2)).
#Ephraim - I've replaced the recursive code with "while" loop. It's running more faster.
int nextPrime(int M) {
while(!isPrime(++M))
// no need ++M; as I already added in the isPrime method's parameter.
return M;
}
boolean isPrime(int M) {
for(int i = 2; i <= M; i++)
if(M % i == 0)
return false;
return true;
}
#Scott Parent- I've tested the the recursive code; "while" loop and steam code (IntStream and LongStream) - the Stream's code is running slowly, very slowly.
Example:
Input value: 60000000000
Output: 60000000029
Elapsed time for recursive algorithm = 7 milliseconds
Output: 60000000029
Elapsed time for traversal algorithm = 4 milliseconds
Output: 60000000029
Elapsed time for LongStream.range(2, number).noneMatch(...) algorithm = 615825 milliseconds
If I use IntStream - the elapsed time is about 230 milliseconds for the max Integer number. It's too much slowly. The "while" loop in nextPrime(int n) is running 1-4 milliseconds for the max integer number, but usage of LongStream for 600000000000 input value - the result I couldnt see in 1 hour.
I'm running now for the 600000000000 long number:
Elapsed time for recursive algorithm = 36 milliseconds
Output: 60000000029
Elapsed time for traversal algorithm = 27 milliseconds
Output: 60000000029
Elapsed time for LongStream.range(2, number).noneMatch(...)
it's still running more than 58 minutes, but it's not finished yet.
long n = 12345;
BigInteger b = new BigInteger(String.valueOf(n));
long res = Long.parseLong(b.nextProbablePrime().toString());
System.out.println("Next prime no. is "+ res);
Generate all prime numbers up to your limit using sieve of eratosthenes. And then input your number n and search if n> prime[i] , prime[i] is the answer.
You can also do the same using recursions like this:
int nextPrime(int M) {
if(!isPrime(M)) M = nextPrime(++M);
return M;
}
boolean isPrime(int M) {
for(int i = 2; i <= Math.sqrt(M); i++)
if(M % i == 0) return false;
return true;
}
My son has written his own algorithm - in one method.
But it's written on python - you can find it here.
On Java it looks like:
static long nextPrime(long number) {
boolean prime = false;
long n = number;
while (!prime && n < number * 2) {
n++;
prime = true;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
prime = false;
break;
}
}
}
return n;
}
Here I add a solution algorithm. First of all, the while loop grabs the next number to be tested within the range of number + 1 to number * 2. Then the number is sent to the isPrime method (which uses Java 8 streams) that iterates the stream to look for numbers that have no other factors.
private static int nextPrime(final int number) {
int i = number + 1;
while (!isPrime(i) && i < number * 2)
i++;
return i;
}
private static boolean isPrime(final int number) {
return number > 1 && IntStream.range(2, number).noneMatch(index -> number % index == 0);
}
Dude check this code.
isPrime() in the while loop checks for the next prime number after incrementing the current prime/non-prime number. I did used the long datatype (that's what I got as assignment).
if (isPrime(num)) {
System.out.println("Current Prime number: " + num);
} else {
long a = getNextPrime(num);
System.out.println("Next Prime:" + a);
}
public static long getNextPrime(long num) {
long nextPrime = 0;
while (true) {
num++;
boolean x = isPrime(num);
if (x) {
nextPrime = num;
break;
}
}
return nextPrime;
}
public static boolean isPrime(long num) {
if (num == 0 || num == 1) {
return false;
}
for (long i = 2; i <= num / 2; ++i) {
if (num % i == 0) {
return false;
}
}
return true;
}
This is functional way of finding next prime number.
public void printFirstNPrimes(long n) {
Stream.iterate(2, i->nextPrime(i))
.limit(n).forEach(System.out::println);
}
public static boolean isPrime(long x) {
return Stream.iterate(2, i->i+1)
.limit((long)(Math.sqrt(x)))
.allMatch(n -> x % n != 0);
}
public static int nextPrime(int x) {
return isPrime(x+1)? x+1 : nextPrime(x+1);
}
So, I was reading the first answer and saw some potential upgrades.
I made them and got a really significant improvement.
The original code could calculate 200000 prime numbers in 22.32s
With a little changes I managed to execute the same operation in 11.41s, with the same results.
Notice I executed the code on my laptop #2.50 GHz, running on IntelIJ.
public static int nextPrime(int n) {
boolean isPrime;
n++;
while (true) {
int sqrt = (int) Math.sqrt(n);
isprime = true;
for (int i = 2; i <= sqrt; i++) {
if (n % i == 0) isPrime = false;
}
if (isPrime)
return n;
else {
n++;
}
}
}
Hope you like it!
public class ClosestPrimeNumber {
static boolean isPrime(int n) {
for (int x = 2; x <= Math.sqrt(n); x++) {
if (n % x ==0) {
return false;
}
}
return true;
}
static int next_forward = 0;
static int next_backward = 0;
static int next = 0;
static int closestPrimeNumberForward(int n) {
if (isPrime(n)) {
next_forward = n;
return next_forward;
}else {
next_forward = n+1;
closestPrimeNumberForward(next_forward);
}
return next_forward;
}
static int closestPrimeNumberBackward(int n) {
if (isPrime(n)) {
next_backward = n;
return next_backward;
}else {
next_backward = n-1;
closestPrimeNumberBackward(next_backward);
}
return next_backward;
}
static int closestCompare(int forward, int backward, int num) {
return (Math.abs(num-backward) > Math.abs(num-forward) ) ? forward : backward;
}
public static void main(String[] args) {
int valor = 102;
System.out.println(closestCompare(closestPrimeNumberForward(valor), closestPrimeNumberBackward(valor), valor));
}
}
public int nextPrime(int input){
int counter;
while(true){
counter = 0;
for(int i = 1; i <= input; i ++){
if(input % i == 0) counter++;
}
if(counter == 2)
return input;
else{
input++;
continue;
}
}
}
This will return the nextPrime but cannot say is most optimal way
It is simple as it execute an infinite while loop which break when
prime number is returned.
In while is finds whether the number is prime or not
If it is prime it returns that number, if not it increment input and continue the while loop
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
My program that calculates the sum of primes is very slow for very large nth term. Please how do I optimize the processing time of my program? The fastest program will be appreciated and the reason why mine is slow for large sets of data. Thanks.
Here's the Java program:
public class SumOfPrimes {
public static void main(String[] args) {
primeNumber(2000000);
}
public static void primeNumber(int nth) {
int counter = 0, i = 2;
while(i>=2) {
if(isPrime(i)) {
counter += i;
}
i++;
if(i == nth) {
break;
}
}
System.out.println(counter);
}
public static boolean isPrime(int n) {
boolean prime = true;
int i;
for(i= 2; i < n; i++) {
if (n % i == 0) {
prime = false;
for (int j = 3; j * j < n; j += 2) {
if (n % j == 0) prime = false;
}
}
}
return prime;
}
}
Well, it's unclear why you have an inner for loop in your isPrime. Removing it will save much time.
Besides, once you find that n is not prime, you should return immediately. Either break out of the loop, or just return false.
Another optimization would be not to test all the number until i < n. It's enough to test until i * i <= n.
public static boolean isPrime(int n) {
int i;
for(i = 2; i * i <= n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
Remember primes you have found, and only test them.
Remove the inner loop.
Test 2, 3, then all odds.
Something like...
public boolean isPrime( ArrayList<Long> primes, long n ){
for( Long t : primes ){
if( n % t == 0 ){
return false;
}
if( t * t > n )return true;
}
return true;
}
public void sumOfPrimes()
{
ArrayList<Long> primes = new ArrayList<Long>();
long n;
double count = 0;
for( n = 2; n < 2000000; n++ ){
if( isPrime( primes, n ) ){
primes.add( n );
count += n;
}
}
}
This should be your isPrime function-
bool isPrime (int number) {
if (number < 2) return false;
if (number == 2) return true;
if (number % 2 == 0) return false;
for (int i=3; (i*i) <= number; i+=2) {
if (number % i == 0 ) return false;
}
return true;
}
Putting together all the answers to my question above, my program has been re-written and it is much faster for very large datasets.
public class SumOfPrimes {
public static void main(String[] args) {
primeNumber(2000000);
}
public static void primeNumber(int nth) {
int i = 2;
long counter = 0;
while(i>=2) {
if(isPrime(i)) {
counter += i;
}
i++;
if(i == nth) {
break;
}
}
System.out.println(counter);
}
public static boolean isPrime (int n) {
if (n < 2) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i=3; (i*i) <= n; i+=2) {
if (n % i == 0 ) return false;
}
return true;
}
}
#aega's solution for the isPrime function did the trick. Now 2 million datasets can be calculated for less than 2 secs.
We no need to test from 1 to n, even 3 to n/2 or 3 to sqrt(n) is also too much for testing for a bigger number.
To make the testing the least, we can only test n with the previous prime that have been found up to sqrt(n), like what mksteve has mentioned.
static List<Integer> primes = new ArrayList<>();
static boolean isPrime (int number) {
if (number < 2) return false;
if (number == 2) return true;
if (number % 2 == 0) return false;
int limit = (int) Math.sqrt(number);
for (i : primes) {
if (i > limit) break;
if (number % i == 0 ) return false;
}
return true;
}
public static void primeNumber(int nth) {
int i = 2;
long counter = 0;
while(i <= nth) {
if(isPrime(i)) {
counter += i;
primes.add(i);
}
i++;
}
System.out.println(counter);
}
A faster program will be to store the generated prime numbers in an array and use only those elements for divisibility check. The number of iterations will reduce dramatically. An element of self-learning is there in this.
I don't have time right now. But, when I'm free, will write a java code to implement this.
Use the power of Lambda for dynamic functional referencing and streams for optimized performance with inbuilt filter conditions.
public static boolean isPrime(final int number) {
return IntStream.range(2,(long) Math.ceil(Math.sqrt(number + 1))).noneMatch(x -> number % x == 0);
}
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
import java.util.*;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
public class helloworld {
public static int[]array = new int[28124];
public static List<Integer> abundant = new ArrayList<Integer>();
public static void main(String []args)
throws IOException {
System.out.println("Answer: " + SumNonAbundant());
}
public static int SumNonAbundant() {
int sum = 0;
abundant.add(12);
GetAbundant(28123);
for (int i = 1; i <= 28123; i++) {
if (checkForSum(i)) {
System.out.println(i);
sum+=i;
}
}
return sum;
}
public static int SumOfDivisors(int num) {
int sum = 0;
for (int i = num - 1; i > 0; i--) {
if (num % i == 0) {
sum += i;
}
}
return sum;
}
public static void GetAbundant(int num) {
for (int i = 13; i <= num ; i++) {
int sum = SumOfDivisors(i);
if ( sum > i) {
System.out.println(i + " " + sum);
abundant.add(i);
}
}
}
public static boolean checkForSum(int num) {
int start = 0;
int end = abundant.size() - 1;
while (start < end) {
if (abundant.get(start) == num) {
return false;
}
else if (abundant.get(end) == num) {
return false;
}
else if (abundant.get(start)*2 == num) {
return false;
}
else if (abundant.get(end)*2 == num) {
return false;
}
else if (abundant.get(start) + abundant.get(end) == num) {
return false;
}
else if (abundant.get(start) + abundant.get(end) < num) {
start++;
}
else if (abundant.get(start) + abundant.get(end) > num) {
end--;
}
}
return true;
}
}
When I run this code, I get "Answer: 4178876", however, the correct answer I think is 4178971.
Really not sure whats the issue here, feel like I'm missing something small but I can't see it. Any help would be greatly appreciated.
in checkForSum change
if (abundant.get(start) == num) {
return true; // not false
}
and remove
else if (abundant.get(end) == num) {
...
}
try
public static boolean checkForSum(int num) {
int start = 0;
int end = abundant.size() - 1;
while (start < end) {
if (abundant.get(start) == num) {
return true;
}
else if (abundant.get(start)*2 == num) {
return false;
}
else if (abundant.get(end)*2 == num) {
return false;
}
else if (abundant.get(start) + abundant.get(end) == num) {
return false;
}
else if (abundant.get(start) + abundant.get(end) < num) {
start++;
}
else if (abundant.get(start) + abundant.get(end) > num) {
end--;
}
}
return true;
}
This is an old question, but I recently ran across this exact same issue (my answer was also 4178876, off by 995), and the only other answer didn't help me figure out what I was doing was wrong.
My issue was that I was removing the abundant numbers themselves as well as those numbers that are the sums of two abundant numbers. That is, I was removing 12, 18, 20 ... as well as 12 + 12, 12 + 18, 12 + 20, 18 + 20, ...
The singletons should not be removed before summing.
So this is problem 3 from project Euler. For those who don't know, I have to find out the largest prime factor of 600851475143. I have the below code:
import java.lang.Math;
// 600851475143
public class LargestPrimeFactor {
public static void main(String[] stuff) {
long num = getLong("What number do you want to analyse? ");
long[] primes = primeGenerator(num);
long result = 0;
for(int i = 0; i < primes.length; i++) {
boolean modulo2 = num % primes[i] == 0;
if(modulo2) {
result = primes[i];
}
}
System.out.println(result);
}
public static long[] primeGenerator(long limit) {
int aindex = 0;
long[] ps = new long[primeCount(limit)];
for(long i = 2; i < limit + 1; i++) {
if(primeCheck(i)) {
ps[aindex] = i;
aindex++;
}
}
return ps;
}
public static boolean primeCheck(long num) {
boolean r = false;
if(num == 2 || num == 3) {
return true;
}
else if(num == 1) {
return false;
}
for(long i = 2; i < Math.sqrt(num); i++) {
boolean modulo = num % i == 0;
if(modulo) {
r = false;
break;
}
else if(Math.sqrt(num) < i + 1 && !modulo) {
r = true;
break;
}
}
return r;
}
public static int primeCount(long limit) {
int count = 0;
if(limit == 1 || limit == 2) {
return 0;
}
for(long i = 2; i <= limit; i++) {
if(primeCheck(i)) {
count++;
}
}
return count;
}
public static long getLong(String prompt) {
System.out.print(prompt + " ");
long mrlong = input.nextLong();
input.nextLine();
return mrlong;
}
}
But when I test the program with something (a lot) smaller than 600851475143, like 100000000, then the program takes its time - in fact, 100000000 has taken 20 minutes so far and is still going. I've obviously got the wrong approach here (and yes, the program does work, I tried it out with smaller numbers). Can anyone suggest a less exhaustive way?
public static void main(String[] args) {
long number = 600851475143L;
long highestPrime = -1;
for (long i = 2; i <= number; ++i) {
if (number % i == 0) {
highestPrime = i;
number /= i;
--i;
}
}
System.out.println(highestPrime);
}
public class LargestPrimeFactor {
public static boolean isPrime(long num){
int count = 0;
for(long i = 1; i<=num/2 ; i++){
if(num % i==0){
count++;
}
}
if(count==1){
return true;
}
return false;
}
public static String largestPrimeFactor(long num){
String factor = "none";
for(long i = 2; i<= num/2 ; i++){
if(num % i==0 && isPrime(i)){
factor = Long.toString(i);
}
}
return factor;
}
public static void main(String[] args) {
System.out.println(largestPrimeFactor(13195));
}
}
I have done several dozen of the challenges on Project Euler. Some of the questions can be solved with brute force (they recommend not to do this) but others require "out of the box" thinking. You cannot solve that by problem with brute force.
There is lots of help on the web to lead you in the right direction, for example:
http://thetaoishere.blogspot.com.au/2008/05/largest-prime-factor-of-number.html
The number of prime factors a number can have is always less than sqrt of that number so that there is no need to iterate through the number n to find its largest prime factor.
See this code.
public class LargestPrimeFactor {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
long num=sc.nextLong();
if(num>0 && num<=2)
{
System.out.println("largest prime is:-" + num);
System.exit(0);
}
int i=((Double)Math.sqrt(num)).intValue();
int j=3;
int x=0;
//used for looping through the j value which can also be a prime. for e.g in case of 100 we might get 9 as a divisor. we need to make sure divisor is also a prime number.
int z=0;
//same function as j but for divisor
int y=3;
int max=2;
//divisor is divisible
boolean flag=false;
//we found prime factors
boolean found=false;
while(x<=i)
{
y=3;
flag=false;
if(num % j ==0)
{
if(j>max)
{
for(z=0;z<Math.sqrt(j);z++)
{
if(j!=y && j % y==0)
{
flag=true;
}
y+=2;
}
if(!flag)
{
found=true;
max=j;
}
}
}
j+=2;
x++;
}
if(found){
System.out.println("The maximum prime is :- " + max);
}
else
{
System.out.println("The maximum prime is :- " + num);
}
}
}
change
for(long i = 2; i <= limit; i++)
to
// add the one for rounding errors in the sqrt function
new_limit = sqrt(limit) + 1;
// all even numbers are not prime
for(long i = 3; i <= new_limit; i+=2)
{
...
}
Factoring 1,000,000 for example instead of iterating 1,000,000 times
the thing only needs to do around 500 iterations.
I'm trying to find the sum of the prime numbers < 2,000,000. This is my solution in Java but I can't seem get the correct answer. Please give some input on what could be wrong and general advice on the code is appreciated.
Printing 'sum' gives: 1308111344, which is incorrect.
Edit:
Thanks for all the help. Changed int to long and < to <= and it worked flawlessly, except for being an inefficient way of finding prime numbers :)
/*
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
*/
class Helper{
public void run(){
Integer sum = 0;
for(int i = 2; i < 2000000; i++){
if(isPrime(i))
sum += i;
}
System.out.println(sum);
}
private boolean isPrime(int nr){
if(nr == 2)
return true;
else if(nr == 1)
return false;
if(nr % 2 == 0)
return false;
for(int i = 3; i < Math.sqrt(nr); i += 2){
if(nr % i == 0)
return false;
}
return true;
}
}
class Problem{
public static void main(String[] args){
Helper p = new Helper();
p.run();
}
}
The result will be too large to fit into an integer, so you are getting an overflow. Try using a BigInteger or a long instead. In this case a long is enough.
You're treating as prime those numbers that are only divisible by their square root (like 25). Instead of i < Math.sqrt(nr) try i <= Math.sqrt(nr).
That's a really inefficient way to find primes, incidentally.
Your isPrime doesn't work for squares. isPrime(9) returns true.
As already stated errors were two:
you used an int that is not big enough to hold that sum.. you should have used a long
you used < instead that <=, and it was a wrong guard for the cycle
Apart from that what you are doing is really inefficient, without going too deep inside this class of algorithms (like Miller-Rabin test) I would suggest you to take a look to the Sieve of Eratosthenes.. a really old approach that teaches how to treat a complex problem in a simple manner to improve elegance and efficiency with a trade-off of memory.
It's really cleaver: it keeps track of a boolean value for every prime up to your 2 millions that asserts if that number is prime or not. Then starting from the first prime it excludes all the successive numbers that are obtained by multiplying the prime it is analyzing for another number. Of couse more it goes and less numbers it will have to check (since it already excluded them)
Code is fair simple (just wrote it on the fly, didn't check it):
boolean[] numbers = new boolean[2000000];
long sum = 0;
for (int i = 0; i < numbers.length; ++i)
numbers[i] = true;
for (int i = 2; i < numbers.length; ++i)
if (!numbers[i])
continue;
else {
int j = i + i;
while (j < 2000000) {
numbers[j] = false;
j += i;
}
}
for (int i = 2; i < 2000000; ++i)
sum += numbers[i] ? i : 0;
System.out.println(sum);
Of course this approach is still unsuitable for high numbers (because it has to find all the previous primes anyway and because of memory) but it's a good example for starters to think about problems..
by using Sieve of Eratosthenes effectively, i solved the problem, here is my code
public class SumOfPrime {
static void findSum()
{
long i=3;
long sum=0;
int count=0;
boolean[] array = new boolean[2000000];
for(long j=0;j<array.length;j++)
{
if((j&1)==0)
array[(int)j]=false;
else
array[(int)j]=true;
}
array[1]=false;
array[2]=true;
for(;i<2000000;i+=2)
{
if(array[(int)i] & isPrime(i))
{
array[(int)i]=true;
//Sieve of Eratosthenes
for(long j=i+i;j<array.length;j+=i)
array[(int)j]=false;
}
}
for(int j=0;j<array.length;j++)
{
if(array[j])
{
//System.out.println(j);
count++;
sum+=j;
}
}
System.out.println("Sum="+sum +" Count="+count);
}
public static boolean isPrime(long num)
{
boolean flag=false;
long i=3;
long limit=(long)Math.sqrt(num);
for(;i<limit && !(flag);i+=2)
{
if(num%i==0)
{
flag=false;
break;
}
}
if(i>=limit)
flag=true;
return flag;
}
public static void main(String args[])
{
long start=System.currentTimeMillis();
findSum();
long end=System.currentTimeMillis();
System.out.println("Time for execution="+(end-start)+"ms");
}
}
and the output is
Sum=142913828922 Count=148933
Time for execution=2360ms
if you have doubt, please do tell
Here is my solution
public class ProjectEuler {
public static boolean isPrime(int i) {
if (i < 2) {
return false;
} else if (i % 2 == 0 && i != 2) {
return false;
} else {
for (int j = 3; j <= Math.sqrt(i); j = j + 2) {
if (i % j == 0) {
return false;
}
}
return true;
}
}
public static long sumOfAllPrime(int number){
long sum = 2;
for (int i = 3; i <= number; i += 2) {
if (isPrime(i)) {
sum += i;
}
}
return sum;
}
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(sumOfAllPrime(2000000));
}
}