Next Prime number Java only working with certain numbers - java

This function its only working for certain numbers, but for 15, or 5 it does not give me correct next prime.
public static int nextPrime(int n) {
boolean isPrime = false;
int m = (int) Math.ceil(Math.sqrt(n));
int start = 3;
if (n % 2 == 0) {
n = n + 1;
}
while (!isPrime) {
isPrime = true;
for (int i = start; i <= m; i = i + 2) {
if (n % i == 0) {
isPrime = false;
break;
}
}
if (!isPrime) {
n = n + 2;
}
}
return n;
}

You don't need to go upto sqrt(n), you need to go upto sqrt(number) that you are evaluating
for example consider you pass n = 5
it will start loop from 3 and it will end the loop at 4 that is not what you need to find next prime number
outer loop
start from n + 1 until you find prime
inner loop
you should start from 3 and sqrt(numberUnderIteration)

You're setting your boundary at the square root of the original number only. In order for you to check if every next number works, you need to recalculate the boundary whenever the n value is changed. So, put int m = (int) Math.ceil(Math.sqrt(n)); inside of your while loop.
You also need to increment n by 1 before you start any calculations, or it will accept n itself as a prime number if it is one. For example, nextPrime(5) would return 5 because it passes the conditions.
And finally, you don't need to increment n by 2 at the end of your while loop because if you are on an even number, it will break out (keep adding 2 to an even number will always be even). I've commented the part of your code that I changed:
public static int nextPrime(int n) {
boolean isPrime = false;
int start = 2; // start at 2 and omit your if statement
while (!isPrime) {
// always incrememnt n at the beginning to check a new number
n += 1;
// redefine max boundary here
int m = (int) Math.ceil(Math.sqrt(n));
isPrime = true;
// increment i by 1, not 2 (you're skipping numbers...)
for (int i = start; i <= m; i++) {
if (n % i == 0) {
isPrime = false;
break;
}
}
// you don't need your "if (!isPrime)..." because you always increment
}
return n;
}
public static void main(String[] args) {
System.out.println(nextPrime(15)); // 17
System.out.println(nextPrime(5)); // 7
System.out.println(nextPrime(8)); // 11
}

You need to compute m inside the for loop.
while (!isPrime) {
isPrime = true;
int m = (int) Math.ceil(Math.sqrt(n));
// do other stuff

Your code works fine except when a prime number is given as input, your method returns input itself.
Example if 5 is your input nextPrime(5) returns 5. If you want 7 (next prime number after 5) to be returned in this case.
Just add n=n+1; at the start of your method. Hope this helps

Just for fun, I coded a quick Prime class that tracks known primes, giving a huge performance boost to finding multiple large primes.
import java.util.ArrayList;
public class Primes {
private static ArrayList<Integer> primes = new ArrayList<Integer>();
public static int nextPrime(int number){
//start it off with the basic primes
if(primes.size() == 0){
primes.add(2);
primes.add(3);
primes.add(5);
primes.add(7);
}
int idx = primes.size()-1;
int last = primes.get(idx);
//check if we already have the prime we are looking for
if(last > number){
//go to the correct prime and return it
boolean high = false;
boolean low = false;
int prevIdx = 0;
int spread = 0;
//keep finagling the index until we're not high or low
while((high = primes.get(idx-1) > number) || (low = primes.get(idx) <= number)){
spread = Math.abs(prevIdx-idx);
//because we always need to move by at least 1 or we will get stuck
spread = spread < 2 ? 2: spread;
prevIdx = idx;
if(high){
idx -= spread/2;
} else if(low){
idx += spread/2;
}
};
return primes.get(idx);
}
/*FIND OUR NEXT SERIES OF PRIMES*/
//just in case 'number' was prime
number++;
int newPrime = last;
//just keep adding primes until we find the right one
while((last = primes.get(primes.size()-1)) < number){
//here we find the next number
newPrime += 2;
//start with the assumption that we have a prime, then try to disprove that
boolean isPrime = true;
idx = 0;
int comparisonPrime;
int sqrt = (int) Math.sqrt(newPrime);
//make sure we haven't gone over the square root limit- also use post-increment so that we use the idx 0
while((comparisonPrime = primes.get(idx++)) <= sqrt){
if(newPrime % comparisonPrime == 0){
isPrime = false;
}
}
if(isPrime){
primes.add(newPrime);
}
}
return last;
}
}
And here is the test:
public class Test {
public static void main(String[] args){
long start;
long end;
int prime;
int number;
number = 1000000;
start = System.currentTimeMillis();
prime = Primes.nextPrime(number);
end = System.currentTimeMillis();
System.out.println("Prime after "+number+" is "+prime+". Took "+(end-start)+" milliseconds.");
number = 500;
start = System.currentTimeMillis();
prime = Primes.nextPrime(number);
end = System.currentTimeMillis();
System.out.println("Prime after "+number+" is "+prime+". Took "+(end-start)+" milliseconds.");
number = 1100000;
start = System.currentTimeMillis();
prime = Primes.nextPrime(number);
end = System.currentTimeMillis();
System.out.println("Prime after "+number+" is "+prime+". Took "+(end-start)+" milliseconds.");
}
}
This results in the following output:
Prime after 1000000 is 1000003. Took 384 milliseconds.
Prime after 500 is 503. Took 10 milliseconds.
Prime after 1100000 is 1100009. Took 65 milliseconds.
As you can see, this takes a long time the first iteration, but we only have to perform that operation once. After that, our time is cut down to almost nothing for primes less than our first number (since it's just a lookup), and it is very fast for primes that are just a bit bigger than our first one (since we have already done most of the work).
EDIT: Updated search for existing primes using a variation on a Binary Search Algorithm. It cut the search time at least in half.

import java.util.Scanner;
class Testing
{
public static void main(String Ar[])
{
int a = 0, i, j;
Scanner in = new Scanner(System.in);
a = in.nextInt();
for (j = a + 1;; j++)
{
for (i = 2; i < j; i++)
{
if (j % i == 0)
break;
}
if (i == j)
{
System.out.println(j);
break;
}
}
}
}

Here is the perfect code for finding next prime for a given number.
public class NextPrime
{
int nextPrime(int x)
{
int num=x,j;
for( j=num+1;;j++)
{
int count=0;
for(int i=1;i<=j;i++)
{
if(j%i==0)
{
count++;
//System.out.println("entered");
}
//System.out.println(count);
}
if(count==2)
{
System.out.println(" next prime is ");
break;
}
}return j;
}
public static void main(String args[])
{
NextPrime np = new NextPrime();
int nxtprm = np.nextPrime(9);
System.out.println(nxtprm);
}
}

//I hope the following code works exactly.
import java.util.Scanner;
public class NextPrime {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a positive integer number : ");
int n = scanner.nextInt();
for (int x = n + 1;; x++) {
boolean isPrime = true;
for (int i = 2; i < x / 2; i++) {
if (x % i == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
System.out.println("Next prime is : " + x);
break;
}
}
}
}

Related

Algorithm to find prime numbers with odd digits in large range

Given a range of [1, 1000000000] we need to find prime numbers and all the digits of the prime number must be odd. (Example: 23 is not okay, 31 is okay)
If we go on by looping through each number and checking if it is prime etc, it is very slow. Is there a way to make this close to O(N) ?
I tried to eliminate as much as possible by looking at digits first. But after eliminating numbers with even digits the prime test is too slow.
for all numbers in [1, N]
check all digits, if any even digit, continue
check primality (this step is very slow)
And the primality test should not be very complex (probabilistic etc. is not possible, it must be possible to implement in a few minutes). The one I use is:
private static boolean isPrime(int n) {
boolean isPrime = true;
for (int divisor = 2; divisor <= n / 2; divisor++) {
if (n % divisor == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
Maybe there is a trick to ensure a quick primality test but I couldn't find. Any suggestions? Thanks for reading.
You don't need to check all milliard numbers. Generate all numbers with only odd digits - there are at most 5^9~2 millions of them. Exclude those ending with 5 and not generate numbers divisible by 3 (in the moment of the last digit generation)
Then check these numbers for primality. Note that loop limit might be sqrt(n)
Ideone
class Ideone
{
static int oddcnt;
public static void checkprime(int x) {
for (int i=3; i <= Math.sqrt(x); i +=2)
if ((x % i) == 0)
return;
oddcnt++;
}
public static void genodd(int x, int curlen, int maxlen) {
x *= 10;
for (int i=1; i<10; i+=2) {
int nx = x + i;
checkprime(nx);
if (curlen < maxlen)
genodd(nx, curlen + 1, maxlen);
}
}
public static void main (String[] args) throws java.lang.Exception
{
genodd(0, 1, 8);
System.out.println(oddcnt);
}
}
The best way I can think of is to run a Prime Sieve of Eratosthenes to find all the primes in the range (0; sqrt(1000000000)) - which is around (0, 31622) - and time complexity O(n*log(log(n))) where n=31622. We will need those prime for a faster primality test.
Then, just loop through each number with odd digits - there are 5^10 = 9765625 ~ 10000000 such numbers. You saved 1000 times compared to iterating through all number in the original range.
The primality test using the primes we found in step 1 can be fast, as you only need to check with primes < sqrt(n), and you already have the primes. Even for the largest number in the range which is 999999999, the number of candidate primes is just 3432.
The following is a Java implementation
public class Execute {
private ArrayList<Long> primes = new ArrayList<>();
#org.junit.Test
public void findOddDecimalPrimes() {
primeSieve(32000);
System.out.println(primes.size());
for (int i = 0; i < 9765625; i++) {
String inBase5 = convertFromBaseToBase(i);
long evenDec = convertToOddDecimal(inBase5);
if (isPrime(evenDec)) {
System.out.println(evenDec);
}
}
}
private String convertFromBaseToBase(long i) {
return Long.toString(i, 5);
}
private long convertToOddDecimal(String str) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
s.append(1 + 2 * Integer.parseInt("" + str.charAt(i)));
}
return Long.parseLong(s.toString());
}
private boolean isPrime(long n) {
for (int i = 0; i < primes.size(); i++) {
if (primes.get(i) * primes.get(i) > n) break;
long divisor = n / primes.get(i);
if (divisor * primes.get(i) == n) return false;
}
return true;
}
/**
* References: www.geeksforgeeks.org
*/
private void primeSieve(int n)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
boolean prime[] = new boolean[n+1];
for(int i=0;i<n;i++)
prime[i] = true;
for(int p = 2; p*p <=n; p++)
{
// If prime[p] is not changed, then it is a prime
if(prime[p] == true)
{
// Update all multiples of p
for(int i = p*p; i <= n; i += p)
prime[i] = false;
}
}
for (int i = 2; i < prime.length; i++) {
if (prime[i]) this.primes.add(Long.valueOf(i));
}
}
}
If your numbers are in order, you can optimize your isPrime function.
Here is a js sample version.
var primes = [];
function checkDigits(n) {
while(n > 1) {
var d = n % 10;
if ( d % 2 == 0) { return false; }
n = parseInt(n/10,10);
}
return true;
}
function isPrime(n) {
for(var i = 1; i < primes.length; i++) {
if(n % primes[i] == 0) {
return false;
}
}
var lastPrime = primes.length > 2 ? primes[primes.length - 1] : 1;
var inc = 2;
for(var i = lastPrime + inc; i < Math.sqrt(n); i += inc) {
if(n % i == 0) {
return false;
}
}
primes.push(n);
return true;
}
for(var i = 1; i < 100; i++) {
if(checkDigits(i) && isPrime(i)) {
console.log(i);
}
}
This is an open question in math and computer science in general.
In a nutshell no, there is no know way to solve that problem in O(1) to get your loop running in O(N) over the whole range.
If you solve that, dont tell anyone, and go get rich by breaking most of the encryptions today that use large prime numbers.
What you could do though, is make the loop over the devisor a bit smaller by useing sqrt(n).
That will bring that inner loop down from O(N^2) to O(sqrt(N))
And the whole complexity from O(N^2) to O(N*sqrt(N))=O(N^(3/2))
Anotger optimization would be to check the odd digits first beforre doing the complex Prime calculation

How to generate huge amount of prime numbers in java?

In order to solve a question I have to generate a list of prime numbers from 1 to 3000000, so I tried several ways to do this and unfortunately all failed...
First try: because all prime numbers bigger than 2 are odd numbers, so I first generate a list of odd numbers started with 3 called allOddNums. And then I generate a list of all composite numbers called allComposite. Then I remove all the number in allComposite from allOddNums to obtain prime numbers. Here is my code:
/** Prime Numbers Generation
* Tony
*/
import java.util.*;
public class PrimeNumG {
public static void main(String[] args) {
List <Long> allOddNums = new ArrayList<Long>();
for (long i = 3; i < 200; i += 2) {
allOddNums.add(i);
}
// composite number generator:
List <Long> allComposite = new ArrayList<Long>();
for (long a = 2; a < Math.round(Math.sqrt(3000000)); a += 2) {
for (long b = 2; b < Math.round(Math.sqrt(3000000)); b += 2) {
allComposite.add(a*b);
}
}
// remove duplicated:
Set <Long> hs = new HashSet<Long>();
hs.addAll(allComposite);
allComposite.clear();
allComposite.addAll(hs);
// remove all composite from allRealNums = allPrime
allOddNums.removeAll(allComposite);
allOddNums.add(0, (long)2);
System.out.printf("%s ", allOddNums);
Scanner sc = new Scanner(System.in);
int times = sc.nextInt();
for (int i = 0; i < times; i++) {
int index = sc.nextInt();
System.out.print(allOddNums.get(index) + " ");
}
}
}
In this case, when I need to generate a few prime numbers it works fine. However, if I want to generate until 3000000 it fails me(used up memory).
Second try: I searched online and find an algorithm called sieve of Eratosthenes. then I first generate 2, 3, 5, 7, 9...(all odd numbers + 2), then I remove every 3rd number after 3 and every 5th number after 5. The code is as below:
/** Prime Number Generator
* Tony
*/
import java.util.*;
public class Solution61 {
public static void main(String[] args) {
List<Long> l1 = new ArrayList<Long> ();
// l1 generator: 3 5 7 9 11 ...
for (long d = 3; d < 100; d += 2) {
l1.add(d);
}
l1.add(1, (long)2); // 2 3 5 ...
removeThird(l1); // rm 3rd after 3
removeFifth(l1); // rm 5th after 5, now the l1 will be prime number
Scanner sc = new Scanner(System.in);
int times = sc.nextInt();
for (int i = 0; i < times; i++) {
int index = sc.nextInt();
System.out.print(l1.get(index) + " ");
}
}
/** removeThird : remove every 3rd number after 3
* param List | return void
*/
private static void removeThird(List<Long> l) {
int i = 1;
int count = 0;
while (true) {
if (count == 3) {
l.remove(i);
count = 1;
}
i ++;
count ++;
if (i > l.size()) {
break;
}
}
}
/** removeThird : remove every 5th number after 5
* param List | return void
*/
private static void removeFifth(List<Long> l) {
int i = 2;
int count = 0;
while (true) {
if (count == 5) {
l.remove(i);
count = 1;
}
i ++;
count ++;
if (i > l.size()) {
break;
}
}
}
}
This is still not up to the task because it also runs out of memory.
3rd try:
I tried to generate from 1 to the 3000000, and then remove every number is the product of prime number and another number. The code is as below:
/** print all the prime numbers less than N
* Tony
*/
public class primeGenerator {
public static void main(String[] args) {
int n = 3000000;
boolean[] isPrime = new boolean[n];
isPrime[0] = false; // because 1 is not a prime number
for (int i = 1; i < n; i++) {
isPrime[i] = true;
} // we set 2,3,4,5,6...to true
// the real number is always (the index of boolean + 1)
for (int i = 2; i <= n; i++) {
if (isPrime[i-1]) {
System.out.println(i);
for (int j = i * i; j < n; j += i /* because j is determined by i, so the third parameter doesn't mater*/) {
isPrime[j-1] = false;
}
}
}
}
}
it still fails me, well guess 3000000 is really a big number huh? Is there any simple and brilliant rookie-friendly way to generate prime numbers below 3000000? Thx!
fourth try:
#jsheeran Is this code below what your answer means? when I hit 1093 it gets slower and slower and my IDE still crashed. Plz tell me if I misinterprete your approach, thx!
/** new approach to find prime numbers
* Tony
*/
import java.util.*;
public class PrimeG {
/** isPrime
* To determine whether a number is prime by dividing the candidate number by each prime in that list
*/
static List<Long> primes = new ArrayList<Long> ();
private static void isPrime(long n) {
boolean condition = true;
for (int i = 0; i < primes.size(); i++) {
if (n % primes.get(i) == 0) {
condition = condition && false;
}
}
if (condition) {
findNextPrime(n);
}
}
/** findNextPrime
* expand the list of prime numbers
*/
private static void findNextPrime(long n) {
primes.add(n);
}
public static void main(String[] args) {
primes.add((long)2);
primes.add((long)3);
primes.add((long)5);
primes.add((long)7);
for (int i = 8; i < 3000000; i++) {
isPrime(i);
System.out.printf("%s", primes);
}
}
}
Fixed implementation of Sieve of Eratosthenes (your third try). I believe it should satisfy your needs.
public static void main (String[] args) throws java.lang.Exception {
int n = 3000000;
boolean[] isPrime = new boolean[n+1];
for (int i = 2; i <= n; i++) {
isPrime[i] = true;
}
for (int factor = 2; factor*factor <= n; factor++) {
if (isPrime[factor]) {
for (int j = factor; factor*j <= n; j++) {
isPrime[factor*j] = false;
}
}
}
for (int i = 2; i <= n; i++) {
if (isPrime[i]) System.out.println(i);
}
}
An alternative approach would be to begin with a list of primes consisting of 2 and 3. Have a method isPrime(int) to determine whether a number is prime by dividing the candidate number by each prime in that list. Define another method, findNextPrime(), which isPrime() can call to expand the list as needed. This approach has far lower overhead than maintaining lists of all odd and composite numbers.
Memory is not an issue in your case. Array of size n = 3000000 can be defined inside the stack frame of a function. Actually array of size 10^8 can be defined safely inside a function. If you need more than that define it as a gloabal variable(Instance variable). Coming to your code there is an IndexOutOfBoundsException in your third code. You need to check for factors of a number only uptill sqrt(n). Factors exist in pairs one factor <=sqrt(n) and other >=sqrt(n). So you can optimize the sieve of Eratosthenes algorithm. Here is a link to one wonderful tutorial on various optimizations of sieve.
This can generate prime numbers up to Integer.MAX_VALUE in few milliseconds. It also doesn't take as much memory as in Sieve of Eratosthenes approach.
public class Prime {
public static IntStream generate(int limit) {
return IntStream.range(2, Integer.MAX_VALUE).filter(Prime::isPrime).limit(limit);
}
private static boolean isPrime(int n) {
return IntStream.rangeClosed(2, (int) Math.sqrt(n)).noneMatch(i -> n % i == 0);
}
}

Project Euler #7 Optimization

I've been noticing a theme with some of the Project Euler problems. They require a huge amount of time to complete. (Problems like Largest Palindrome and 10,001st Prime) I was hoping there could be some way to optimize the code to make it better. I let this one run for over 24 minutes and it didn't finish.
public class Seven
{
public static void main(String[] args)
{
//Declare Variables
int primeCount = 0;
int numCount = 1;
int latestPrime = 0;
while(primeCount <= 10001)
{
if(isPrime(numCount))
{
primeCount++;
latestPrime = numCount;
}
numCount++;
}
System.out.println("The 10,001st prime is: " + latestPrime);
}
//This method will determine if a number is prime
public static boolean isPrime(long num)
{
//Check for even number
if(num % 2 == 0)
return false;
//Check for non-prime odd numbers
for(long i = 3; i <= num; i += 2)
{
if(num % i == 0)
return false;
}
//Return that the number is prime
return true;
}
}
You're doing a lot of repetitions, you don't need to loop through entire number in the for loop, just go until square root.
This runs in a second.
// Check for non-prime odd numbers
for (long i = 3; i <= Math.sqrt(num) +1; i += 2) {
if (num % i == 0)
return false;
}
If you want to optimize even more, you could store prime numbers in an array and only check if the number divisible by the previous prime numbers.
This program prints 10001 first prime numbers. As #Tejash Desai suggested, 2 optimizations could be done:
(1) keep the found prime numbers in a list so that tests of new primes needs to be done only on items inside this list, rather than all odd numbers; and
(2) test againts factors only up to square root of a number.
void printPrimes() {
// Find first 10001 primes
int p = 0;
for (var i = 2; i <= 10001; i++) {
p = nextPrime();
Console.WriteLine("Prime #{0}: {1}", i, p);
}
}
// Set of known primes
List<int> primes = new List<int>() {2};
// Find the prime next to the last one that was found
int nextPrime() {
int k = primes[primes.Count - 1] + 1;
while (!testPrimeUsingKnownSetOfPrimes(k)) {
k = k + 1;
}
primes.Add(k);
return k;
}
// Check if a number is prime, using the set of known primes
bool testPrimeUsingKnownSetOfPrimes(int n) {
foreach (var p in primes) {
// Largest prime factor of a number can't be greater than square root of the number
if (p > Math.Sqrt(n)) {
return true;
}
if (n % p == 0) {
return false;
}
}
return true;
}
PS Written in C#.
Loop only till less than or equal to the square root of n
//Check for non-prime odd numbers for(long i = 3; i <= Math.sqrt(num); i += 2) { if(num % i == 0) return false; }
Also, another optimization would be to keep storing all the primes you've come across till now in an ArrayList and then only traverse the loop in that list.
//Check for non-prime odd numbers for(int i = 0; i <= arrayList.size(); i ++) { if(num % arrayList.get(i) == 0) return false; } arrayList.add(num);

Can find all the prime numbers but doesn't include "2"?

It now can find all the prime numbers in the input range, but it can't find number 2, the smallest prime number.
for(int number=2;number<range;number++){
for(int testDivide=2;testDivide<Math.sqrt(number);testDivide++){
if(number%testDivide!=0) {
System.out.println(number);
}
break;
}
For range 10 it prints:
5
7
9
but no 2.
The reason your code is not producing correct results (missing 2 and 3; including 9) is that your primality test logic is backwards. A number is prime if the inner loop completes without finding any even divisors; instead you are printing the number if you find any non-divisor.
Try this instead:
for( int number = 2; number < range; number++) {
boolean divisible = false;
int limit = (int) Math.sqrt(number);
for (int testDivide = 2; !divisible && testDivide <= limit; testDivide++) {
divisible = number % testDivide == 0;
}
if (!divisible) {
System.out.println(number);
}
}
Note that a much more efficient way to generate all primes in a range is the Sieve of Eratosthenes.
check the code here:
package core;
public class Test2 {
public static void main(String[] args) {
int cnt = 0;
for (int i = 2;; i++) {
if (Priem(i)) {
cnt++;
System.out.println(i);
if (cnt == 200)
break;
}
}
}
public static boolean Priem(int n) {
for (int i = 2; i < n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
}
Note that one of the best ways to generate a list of prime numbers is the "Sieve of Erwhatshisface":
Create a list of consecutive integers starting with 2, up to the max number you'd like to search. Take the first non-zero number in the list (2) and repeatedly step 2 from that location, zeroing out every 2nd list element.
Next take the second non-zero number (3) and repeatedly step 3 from that location, zeroing. Continue with each non-zero value in the list, until you've processed all of them (or at least halfway through, at which point you'll be stepping beyond the end of the list).
The non-zero numbers remaining are all primes.
Reposting code here as not fit in comments:
public static void main(String[] args) {
int cnt = 0;
for (int i = 2;; i++) {
if(i==2){
System.out.println(i);
continue;
}
if (Priem(i)) {
cnt++;
System.out.println(i);
if (cnt == 200)
break;
}
}
}
public static boolean Priem(int n) {
for (int i = 2; i <Math.sqrt(n)+1; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
I think you have your for loop a little mixed up.
for(int testDivide=2;testDivide<Math.sqrt(number);testDivide++){
}
Not sure why you are stopping when testDivide is equal to sqrt(number), you should stop when testDivide is greater than.
Also inside your inner for loop isn't correct either:
if(number%testDivide!=0) {
System.out.println(number);
}
break;
Basically all this will do is check to see of the number is divisible by 2 and then break. You only need to break when you find a number which cleanly divides (number%testDivide==0). Maybe keep a boolean which you set to true when you break and only print after the inner for loop finishes if that boolean is false.
Something along the lines:
for (int number=2; number<range; number++){
boolean found = false;
int limit = (int)Math.sqrt(number);
for (int testDivide=2; testDivide<=limit; testDivide++){
if(number%testDivide==0) {
found = true;
break;
}
}
if (!found) System.out.println(number);
}
In your code when number is 2, sqrt(2) is 1.41 and control doesn't go into the loop. I didn't get the logic behind iterating upto sqrt(number). Try this code
public class Test {
public static void main(String[] args) {
int range = 500; //I assume
for (int i = 2; i< range; i++) {
if (isPrime(i)) {
System.out.println(i);
}
}
}
public static boolean isPrime(int number) {
for (int i = 2; i <= number/2; i++) {
if (number % i == 0) {
return false;
}
if(i % 2 == 1) {
i++; //If not divided by 2 then
// need not to check for any even number
// Essentially incrementing i twice hereafter
}
}
return true;
}
}

Wrong Answer for Project Euler 50

I am attempting Problem 50 of project Euler.
The prime 41, can be written as the sum of six consecutive primes:
41 = 2 + 3 + 5 + 7 + 11 + 13 This is the longest sum of consecutive
primes that adds to a prime below one-hundred. The longest sum of
consecutive primes below one-thousand that adds to a prime, contains
21 terms, and is equal to 953. Which prime, below one-million, can be
written as the sum of the most consecutive primes?
Here is my code:
public class consPrime
{
static int checker(int ar[],int num,int index) //returns no.of consecutive
{ //primes for the given num
while(true)
{
int temp=num;
for(int i=index;i>=0;i--)
{
temp=temp-ar[i];
if(temp==0)
{
return (index-i+1);
}
}
index--;
if(index==0)
return 0;
}
}
public static void main(String args[])
{
int n=100000;
int ar[]=new int[n];
int total=0;int flag;
for(int i=2;i<1000000;i++) //Generates an array of primes below 1 million
{
flag=1;
for(int j=2;j<=Math.sqrt(i);j++)
{
if(i%j==0)
{
flag=0;
break;
}
}
if(flag==1)
{
ar[total]=i;
total++;
}
}
int m=0;
int Big=0;
for(int i=total;i>=0;i--) //Prints the current answer with no.of prime
{
m=checker(ar,ar[i],i-1);
if(Big<=m)
{Big=m;
System.out.println(ar[i]+" "+Big);
}
}
}
}
Basically it just creates a vector of all primes up to 1000000 and then loops through them finding the right answer. The answer is 997651 and the count is supposed to be 543 but my program outputs 990707 and 75175 respectively. What might be wrong?
Several big problems:
Some minor problem first: learn to proper indent your code, learn to use proper naming convention. In Java, variable names uses camelCasing while type name uses PascalCasing.
Lots of problems in your logics: you loop thru the prime number array, until you hit zero or until looped thru all numbers in the array. However, please be awared that, there is underflow/overflow for integer. It is possible that the "temp" keeps on deducts and become negative and become positive and so-on-and-so-forth and hit zero. However that's not the correct answer
You only tried to find the consecutive numbers that ends at index - 1. For example, to check for prime number at index 10, you are finding consecutive primes from index 9 backwards. However consecutive prime sum up to your target number rarely (in fact almost never, except for 5) contains the "previous" prime number. The whole logic is simply wrong.
Not to mention the incorrect parameters you passed for checker, which is mentioned by comment of user #pm-77-1
Here is another approach that takes 43 ms.
It is based on the following approach:
1) The primes <= 1000000 are generated using a sieve
2) It iterates in O(n2) through all numbers and it counts the consecutive primes. The first loop changes the first element of the sequence, the second one takes the elements starting from that position and adds them to a sum. If the sum is prime and it consists of the biggest number of primes, than it is kept in a variable.
import java.util.ArrayList;
import java.util.List;
public class P50 {
private final static int N = 1_000_000;
public static void main(String[] args) {
boolean primes[] = generatePrimes(N);
List<Integer> primeIntegers = new ArrayList<Integer>();
for (int i = 0; i < primes.length; i++) {
if (primes[i]) {
primeIntegers.add(i);
}
}
int count = 0;
int sum = 0;
int finalSum = 0;
int finalCount = 0;
int totalPrimes = primeIntegers.size();
for (int start = 0; start < totalPrimes; start++) {
sum = 0;
count = 0;
for (int current = start; current < totalPrimes; current++) {
int actual = primeIntegers.get(current);
sum += actual;
if ( sum >= N ) {
break;
}
if ( primes[sum] ) {
if ( count > finalCount ) {
finalCount = count;
finalSum = sum;
}
}
count++;
}
}
System.out.println(finalSum);
}
private static boolean[] generatePrimes(int n) {
boolean primes[] = new boolean[n];
for (int i = 0; i < n; i++) {
primes[i] = true;
}
primes[0] = false;
primes[1] = false;
// i = step
for (int i = 2; i * i < n; i++) {
if (primes[i]) {
for (int j = i * i; j < n; j += i) {
primes[j] = false;
}
}
}
return primes;
}
}

Categories

Resources