I can't figure out my error in my PrimeGenerator - java

In the output, I get a 9 where I should be getting an 11!
This occurs after the fifth call to nextPrime(). Every other output is correct except for the 5th one! I have been struggling to determine my error for a few hours now. Sorry if my code is sloppy, this is the way my mind figured out the problem! It was a requirement to use the flag controlled loop.
public class PrimeGenerator
{
private int num = 2;
public PrimeGenerator()
{
}
public int nextPrime()
{
boolean done = false;
for (int n = num; !isPrime(num); n++)
num = n;
if (isPrime(num))
{
done = true;
}
if (done)
{
int prime = num;
num++;
return prime;
}
return num;
}
public static boolean isPrime(int n)
{
boolean result = true;
for (int i = 2; n % i == 0 && i < n; i++)
result = false;
if (n == 2)
result = true;
return result;
}
}
My Tester just calls the nextPrime() method and prints the result.

You get 9 instead of 11 because you have mistake in method isPrime
public static boolean isPrime(int n)
{
boolean result = true;
for (int i = 2; n % i == 0 && i < n; i++)
result = false;
if (n == 2)
result = true;
return result;
}
Look for number 9.
first iteration: i = 2, result = true
n % i => 9 % 2 = 1, so your loop stops before first iteration and result didn't changed.
Try to change method isPrime (Updated as commented #John in comments)
public static boolean isPrime(int n)
{
if( n % 2 == 0 ) {
return false;
}
double root = Math.sqrt(n);
for ( int i = 3; i < root; i+=2 ) {
if( n % i == 0 ) {
return false;
}
}
return true;
}

Your nextPrime method returns num whether or not it is prime. Your code is effectively:
if(isPrime(num))
return num;
}
return num;

So the main problem with your code here is the method for checking if a number is prime. According to number theory, you just need to check that the given number is not divisible by any number between 2 and the root of the given number you want to determine is prime. More formally, if you want to check if a number n is prime, you need to check that n is not divisible by any number between 2 and sqrt(n).
An updated method using this number theory fact is below:
public static boolean isPrime(int n)
{
int root = (int)Math.sqrt(n);
for (int i = 2; i <= root; i++) {
if(n % i == 0) {
return false;
}
}
return true;
}
With this your determination of the prime number would be correct and would be much faster. There are even faster ways of determining primes and generating primes like sieve's algorithm.

Related

How do I get an if statement to check if a user given number is a prime number?

I am writing a very basic program in Java to check if a number given by the user is a prime number.
I have tried to use an if statement to check if the number divided by itself is equal to 1 as well as if it is divided by 1 it equals itself, but when I run the program and enter a number there is no reaction at all from the if statement.
package prime.java;
import java.util.Scanner;
public class Prime {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Welcome to Prime!\nPlease enter a number:");
Scanner Scan = new Scanner (System.in);
int number = Scan.nextInt();
System.out.println(number);
if (number%1 == number && number%number == 1) {
System.out.println(number + " is a prime num");
}
}
}
Am I using the right operators?
This can help you:
static bool isPrime(int number)
{
for (int i = 2; i < number; i++)
{
if((number% i) == 0)
{
// Not Prime
return false;
}
}
// Just Prime!
return true;
}
A prime number is not divisible by any numbers between 2 and (itself - 1).
This way, if you call 'isPrime()' inside the if, this just works.
Hope this can help you!
, but when I run the program and enter a number there is no reaction
at all from the if statement.
This is because the if condition is never fulfilled ( for example : n%n will be 0 always) .
Thus, you can keep a variable i that starts from 2 till number -1 and check if that number divided by i , the remainder should never be 0 .
public class PrimeNumber {
public static void main(String[] args) {
int k = 5;
boolean isPrime = true;
for (int i = 2; i < k; i++) {
if (k % i == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
System.out.println("number " + k + " is prime");
} else {
System.out.println("number " + k + " is not prime");
}
}
}
and the output is :
number 5 is prime
You can write a isPrime function to check if a given number is a prime or not, like below
public static boolean isPrime(int n) {
// Corner case
if (n <= 1) {
return false;
}
// Check from 2 to n-1
for (int i = 2; i < n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
And replace your
if (number%1 == number && number%number == 1)
to
if (isPrime(number)
This is more efficient:
boolean isPrime(int number) {
int root = (int) Math.sqrt(number);
for (int i = 2; i <= root; i++) {
if ((number % i) == 0) {
return false;
}
}
return true;
}
Looks like someone is doing a project Euler problem.
You are close but I would suggest maybe looking into how you check if something actually is a prime number as the other comment suggested.
Research also some specifics of prime numbers, I will give one away which is : no prime number ends with 5. Implementing such rules can drastically reduce your programs run time.
And also you want to check out the correct usage of the modulo (%) operator.
public static boolean isPrime(Long num){
String number = String.valueOf(num);
if(number.length() >= 2 ){
//Lets see if a number ends with 5 if it does it is divisible by 2 and not prime
if(number.endsWith("5")){
return false;
}
}
//No reason to check if a number is prime when it is 2.
else if (num == 2){
return true;
}
//Any number that can be devided by 2 with no remainder clearly isn't prime
else if(num % 2 == 0){
return false;
}
//All other numbers actually need to be checked.
else{
for (Long i = num -1; i > 2; i--) {
if(num % i == 0){
return false;
}
}
}
return true;
}

Return a boolean value using if/else in java

I am trying to write a code to check if a number is prime and return true if it is a prime number using if/else statement.
I am giving the code below, I have written.
It is always showing an exception "missing return statement".
class Main
{
static boolean isPrime(int x)
{
for(int i = 2;i <= x/2;++i)
{
if(x%i == 0)
{
return false;
}
else
{
return true;
}
}
}
public static void main (String args[])
{
boolean prime = isPrime(11);
System.out.println(prime);
}
}
The problem in your code is that you are returning true the first time the modulus is not 0. That's wrong, because you have to make sure that x is not divisible to any of the numbers in range [2, x/2].
Modify your method as follows:
static boolean isPrime(int x)
{
if(x <= 1)
{
return false;
}
boolean ret = true;
for(int i = 2;i <= x/2;++i)
{
if(x%i == 0)
{
ret = false;
break;
}
}
return ret;
}
In this way you break as soon as you are sure the number is not prime. If it's prime it will complete the loop without finding non-zero remainders.
The x<=1 scenarios is the cause of the warning you are experincing, as with those inputs your method exits without encountering a return statement. I just checked for this condition at the beginning of the function.
Finding prime numbers
I just suggested the fix to your isPrime implementation, which is the simpliest way to find prime numbers. Anyway there are smarter ways to find them:
The Siege of Eratosthenes method
You could check only odd numbers, saving half the time
You could check if x belongs to the 6*x±1 set. In fact all prime numbers from number 5 follow this rule
You are not taking into account that the number "x" passed into the method can be zero. If that is the case (x == 0) you loop will not execute and there is a path through the method that does not return TRUE or FALSE.
As explained before, in the existing implementation it is possible that loop is not executed and no return statement is provided after the loop.
Better search for prime numbers would be:
Check for 0 and 1 to return false for them
Check for even numbers: all even numbers except 2 are composite
Check only odd numbers for primality
Check limited range of numbers using "inverse" square root condition: i * i <= n
(Optionally) Exclude negative numbers
Example implementation:
static boolean isPrime(int x) {
int n = Math.abs(x); // exclude negatives
if (n < 2) return false; // exclude 0, 1
if (n % 2 == 0) return n == 2; // exclude even except 2
for (int i = 3; i * i <= n; i += 2) { // check only odd numbers
if (n % i == 0) {
return false;
}
}
return true;
}
Faster implementation using 6n ± 1 rule (thanks Roberto Caboni) could look like this (starting from 5 (6n - 1) and using variable steps 2 and 4):
static boolean isPrimeFaster(int x) {
int n = Math.abs(x);
if (n < 2) return false; // exclude 0, 1
if (n % 2 == 0) return n == 2; // exclude even except 2
if (n % 3 == 0) return n == 3; // exclude multiples of 3
for (int i = 5, j = 2; i * i <= n; i += j, j = j == 2 ? 4 : 2) {
if (n % i == 0) {
return false;
}
}
return true;
}
You need this implementation
static boolean isPrime(int x)
{
If(x==0||x==1) {
return false;
}
for(int i = 2;i <= x/2;++i)
{
if(x%i == 0)
{
return false;
}
}
return true;
}
The compiler is confused because both return statements are conditional. It isn't sure any one of them will happen. Your program will compile if you simply move the return true; outside the for loop.
class Main
{
static boolean isPrime(int x)
{
for(int i = 2;i <= x/2;++i)
{
if(x%i == 0)
{
return false;
}
}
return true;
}
public static void main (String args[])
{
boolean prime = isPrime(11);
System.out.println(prime);
}
}
Your program will not return a correct answer fo x <= 2. We can fix that by adding a few ifs at the beginning.
class Main
{
static boolean isPrime(int x)
{
if (x < 2)
{
return false;
}
if (x == 2)
{
return true;
}
for(int i = 2;i <= x/2;++i)
{
if(x%i == 0)
{
return false;
}
}
return true;
}
public static void main (String args[])
{
boolean prime = isPrime(11);
System.out.println(prime);
}
}
You can improve the performance of your program without too much of a change by limiting your search to sqrt(x) instead of x/2. And now that we are optimising, we might as well only check the odd numbers.
class Main
{
static boolean isPrime(int x)
{
if (x < 2)
{
return false;
}
if (x == 2)
{
return true;
}
if (x % 2 == 0)
{
return false;
}
int limit = (int) Math.sqrt(x);
for(int i = 3; i <= limit; i += 2)
{
if(x%i == 0)
{
return false;
}
}
return true;
}
public static void main (String args[])
{
boolean prime = isPrime(11);
System.out.println(prime);
}
}
Use a boolean variable and set it true when the number is divisible. Also check if the number is less than 2 because one and zero are not primes so return false then.
The problem in your code currently is that you immediately return false or true after the first iteration but you have to check as long as you found a divisor or you run up from 2 until the square root of x This is more accurate to run until the iterator is less or equal than the square root of the prime
If you are interested why to use the square root as running condition check out this answer
Why do we check up to the square root of a prime number to determine if it is prime?
public static void main(String[] args) {
System.out.println(isPrime(0));
System.out.println(isPrime(3));
System.out.println(isPrime(4));
System.out.println(isPrime(5));
System.out.println(isPrime(11));
}
public static boolean isPrime(int x) {
boolean isPrime = true;;
if(x < 2) {
return false;
}
for(int i = 2; i <= Math.sqrt(x); i++) {
if (x % i == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
Generates the output
false
true
false
true
true
java compiler expects isPrime() always returns a boolean.
you can loop and when remaining become 0 return false. and after and loop return true.
static boolean isPrime(int x)
{
for(int i = 2;i <= x/2;++i)
if(x%i == 0)
return false;
return true;
}
class PrimeNumber
{
static boolean isPrime(int x)
{
boolean status = false;
for(int i = 2;i <= x/2;++i)
{
if(x%i == 0)
{
status = false;
}
else
{
status = true;
}
}
return status;
}
public static void main (String args[])
{
boolean prime = isPrime(11);
System.out.println(prime);
}
}
this will solve your problem

find nth prime in java with low time complexity

I'm trying to find a low time complexity solution for finding nth prime.
However there's some method problems I'm quite confused.
Also I want to know is mine has a low time complexity or can it be better?
I've tried two different ways to find the prime while the first one is way too slow, so i changed another one. But the boolean method has some problem which i have no idea.
public static int FInd_NthPrime(int n){
int num=0,j,c=2;
while (true) {
if(isPrime(c)){
num = num+1;
}
c = c+1;
break;
}
return c; // the error happened
}
public static boolean isPrime(int n) {
for (int i = 2; i < Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
public static void print_nth_prime(int num){
int result = FInd_NthPrime(num);
System.out.print(num +" "+result);
}
I expect anyone tell me the mistake in boolean method and is there any better way to make low time complexity for finding the nth prime。
You only have to test odd integers and special case "2".
And when doing the isPrime test, just do the modulo check against existing primes already discovered.
public static int FInd_NthPrime(int n){
int val = 3; // first odd number greater than 2
int result = 0;
if (n <= 1) {
return 2; // special case for 2, the only even prime
}
// build up a Hash table of all discovered primes so far
ArrayList<Integer> primes = new ArrayList<Integer>();
primes.add(2);
while (n > 1) {
if (isPrime(val, primes)) {
n--;
result = val;
}
val += 2; // increment to the next odd integer
}
return result;
}
public static boolean isPrime(int n, ArrayList<Integer> primes) {
if (n == 2) {
return true;
}
int stop = (int)Math.sqrt(n);
for (int divisor : primes) {
if ((n % divisor) == 0) {
return false;
}
if (divisor > stop) {
break;
}
}
//System.out.format("Added %d to prime list\n", n);
primes.add(n);
return true;
}

Optimal way to find next prime number (Java)

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

Finding prime numbers with a custom IsPrime method

I started learning Java about one month ago and today I saw this question I couldn't solve.
The question was:
Write a method named isPrime, which takes an integer as an argument and returns true
if the argument is a prime number, or false otherwise. Demonstrate the method in a complete program.
And the second part says:
Use the isPrime method that you wrote in previous program in a program that
stores a list of all the prime numbers from 1 through 100 in a file.
Here's my code, which doesn't work:
import java.io.*;
public class PrimeNumbers {
public static void main (String args[]) throws IOException {
PrintWriter outputFile = new PrintWriter("PrimeNumber.txt");
int j = 0;
for (int i = 0; i < 100; i++) {
isPrime(i);
outputFile.println("Prime nums are:" + i);
}
}
public static boolean isPrime (int j) {
int i;
for (j = 2; j < i; j++) {
if (i % j == 0) {
return false;
}
if (i == j) {
return true;
}
}
}
}
Your condition for returning true in isPrime - if (i == j) - can never be met, since it's inside a loop whose condition is j < i. Instead, just return true after the loop. If the loop ends without returning false, you know for sure that the input number is prime.
Your code that uses isPrime is not checking the value returned by this method. You must check it in order to decide whether to write the number to the output file.
import java.io.IOException;
import java.io.PrintWriter;
public class PrimeNumbers
{
public static void main(String args[]) throws IOException
{
PrintWriter primeNumbersWriter = new PrintWriter("PrimeNumber.txt");
for (int i = 0; i < 100; i++)
{
// You didn't do anything with the return value of isPrime()
if (isPrime(i))
{
primeNumbersWriter.println("Prime numbers are: " + i);
}
}
// Please close writers after using them
primeNumbersWriter.close();
}
public static boolean isPrime(int prime)
{
// Do not use the number to check for prime as loop variable, also it's
// sufficient to iterate till the square root of the number to check
for (int number = 2; number < Math.sqrt(prime); number++)
{
if (prime % number == 0)
{
return false;
}
}
// You didn't always return a value, it won't let you compile otherwise
return true;
}
}
Prime Number A prime number (or a prime) is a natural number greater
than 1 that has no positive divisors other than 1 and itself.
What should be the logic?
Pass a number to method.
Use loop to start a check of modulo % to find at least one number which can divide the passed number.
Check until we reached the value passedNumber.
If the modulo gives 0 for atleast one, it's not prime thank god!
If modulo is not 0 for any number ...oh man it's Prime.
What are the problems in your code?
You are looping correctly but using the variable j which is the limit and you are incrementing it!
If you want to loop through i < j how can the condition i == j be true?
If method is returning boolean why are you using method as void! Use that returned value.
You can just return false at the end if divisor not found!
We did it...Just try now!
about isPrime: First of all, u should loop for( j = 2; j*j <= i; j++)
the reason for this loop is that if a number isn't prime, its factor must be less or equal to the squared root of i, so there is no need to loop after that point
now, if loop didn't return false - return true`
about second function: use if before checking isPrime - if(isPrime(i)) {add i to list}
see here is your solution.
import java.util.Scanner;
public class Testing {
public static void main(String args[]) {
Scanner scnr = new Scanner(System.in);
int number = Integer.MAX_VALUE;
System.out.println("Enter number to check if prime or not ");
while (number != 0) {
number = scnr.nextInt();
System.out.printf("Does %d is prime? %s %s %s %n", number,
isPrime(number), isPrimeOrNot(number), isPrimeNumber(number));
}
}
/*
* Java method to check if an integer number is prime or not.
* #return true if number is prime, else false
*/
public static boolean isPrime(int number) {
int sqrt = (int) Math.sqrt(number) + 1;
for (int i = 2; i < sqrt; i++) {
if (number % i == 0) {
// number is perfectly divisible - no prime
return false;
}
}
return true;
}
/*
* Second version of isPrimeNumber method, with improvement like not
* checking for division by even number, if its not divisible by 2.
*/
public static boolean isPrimeNumber(int number) {
if (number == 2 || number == 3) {
return true;
}
if (number % 2 == 0) {
return false;
}
int sqrt = (int) Math.sqrt(number) + 1;
for (int i = 3; i < sqrt; i += 2) {
if (number % i == 0) {
return false;
}
}
return true;
}
/*
* Third way to check if a number is prime or not.
*/
public static String isPrimeOrNot(int num) {
if (num < 0) {
return "not valid";
}
if (num == 0 || num == 1) {
return "not prime";
}
if (num == 2 || num == 3) {
return "prime number";
}
if ((num * num - 1) % 24 == 0) {
return "prime";
} else {
return "not prime";
}
}
}

Categories