I'm trying to write a code for the Goldbach's weak conjecture, which states that every odd number greater than 5 can be expressed as the sum of three prime numbers.
I have to print the first three prime numbers that are equal to the given number.
this program works but i get Time Limit Exceeded.
5 < N < 10^18
public static void FindPrimes(int n){
boolean found = false;
if(n%2 == 1 && n > 5){
for(int i=n; i>=2; i--){
for(int j=i; j>=2; j--){
for(int k=j; k>=2; k--){
if(NumberIsPrime(i) && NumberIsPrime(j) && NumberIsPrime(k)){
if(i + j + k == n){
System.out.println(k+" "+j+" "+i);
found = true;
return;
}
}
}
}
}
if(!found){
System.out.println(-1);
}
}
}
public static boolean NumberIsPrime(int x){
if (x == 0 || x == 1){
return false;
}
for (int i = 2; i * i <= x; ++i){
if (x % i == 0){
return false;
}
}
return true;
}
There are a few improvements that could be made. I am certain there are more that I haven't considered.
First, try to memoize(save the primes) as they are calculated in a Set to better control and speed up verifying a number is a prime.
Use the set of primes as divisors to find other primes. They will need to iterated in a ascending order to do this so a SortedSet implementation would be required.
I would check the sums of the candidates first. If they don't add up to n then no need to check if they are prime.
You can reduce your nested loops to two by finding primes a and b and then seeing if n-(a+b) is a prime.
Check this site for better algorithims for finding primes. There are many that have been presented as answers.
Related
I have two methods to find out prime number in java method - 2 working fine but getting wrong output from method one, can any help me where i did wrong in logic. Thanks in advance
My entire code
package prepare;
import java.util.Scanner;
public class Squar {
//Method - 1 to find prime number
boolean isPrime(int num){
int exp = (int)Math.sqrt(num);
for(int i=2;i<exp;i++){
if(exp%2==0){
return false;
}
}return true;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
Squar s = new Squar();
System.out.println("From M1 "+s.isPrime(num));
scan.close();
System.out.println("From M2 "+s.isPrimeNumber(num));
}
//Method - 2 to find prime number
public boolean isPrimeNumber(int number) {
if(number == 1){
return false;
}
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;
}
}
for input : 63 actual out put would be false in prime number but getting
different output from method one
output
63
From M1 true
From M2 false
In isPrime() method, Shouldn't you be checking num % i == 0 rather than exp % 2 == 0?
Change isPrime function like this.
boolean isPrime(int num) {
int exp = (int) Math.sqrt(num);
for (int i = 2; i < exp; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
Because in if condition you are checking exp%2 == 0 . But this statement does not change when iterating on i < exp. So this logic should be on with num % i == 0
Have a look at this line of your code
if(exp%2==0){
it should be num % i
Well I think the culprit is
if(exp%2==0){
and it is causing a problem while iterating i<exp.So you may want to tweak it to
num%i==0
I have tried to give a few other approaches to this issue.
I hope that would be helpful.
I think there is a reason that tempted you to use
(int)Math.sqrt(num);
I have tried to elaborate it below.
Consider below 3 approaches.
All of them are correct but the first 2 approaches have some drawbacks.
Approach 1
boolean isPrime(int num) {
for(int i=2;i<num;i++) {
if(num%i==0)
return false;
}
return true;
}
We have a scope to make it faster.
Consider that if 2 divides some integer n, then (n/2) divides n as well.
This tells us we don't have to try out all integers from 2 to n.
Now we can modify our algorithm:
Approach 2
//checks whether an int is prime or not.
boolean isPrime(int num) {
for(int i=2;2*i<num;i++) {
if(num%i==0)
return false;
}
return true;
}
Finally, we know 2 is the "oddest" prime - it happens to be the only even prime number.
Because of this, we need only check 2 separately, then traverse odd numbers up to the square root of n.
I think this might have tempted you to use (int)Math.sqrt(num);
Approach 3
//checks whether an int is prime or not.
boolean isPrime(int num) {
//check if num is a multiple of 2
if (num%2==0) return false;
//if not, then just check the odds
for(int i=3;i*i<=num;i+=2) {
if(num%i==0)
return false;
}
return true;
}
Hence, we've gone from checking every integer (up to n to find out that a number is prime) to just checking half of the integers up
to the square root.
Is it not an improvement, especially considering when numbers are large.
Well, your first algorithm is almost (replace %2 with %i) correct. I do not know the second algorithm, but i would definitely change it to this form:
public boolean isPrime(int n) {
if (n <= 1) {
return false;
}
for (int i = 2; i < Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Could anyone help me on how to check whether a number is prime using for loop?
From this site.
We learned numbers are prime if the only divisors they have are 1 and itself. Trivially, we can check every integer from 1 to itself (exclusive) and test whether it divides evenly.
For example, one might be tempted to run this algorithm:
//checks whether an int is prime or not.
boolean isPrime(int n) {
for (int i = 2; i < n; i++) {
if (n % i == 0)
return false;
}
return true;
}
This doesn't seem bad at first, but we can make it faster - much faster. Consider that if 2 divides some integer n, then (n/2) divides n as well. This tells us we don't have to try out all integers from 2 to n. Now we can modify our algorithm:
//checks whether an int is prime or not.
boolean isPrime(int n) {
for (int i = 2; 2 * i < n; i++) {
if (n % i == 0)
return false;
}
return true;
}
With some more efficient coding, we notice that you really only have to go up to the square root of n, because if you list out all of the factors of a number, the square root will always be in the middle (if it happens to not be an integer, we're still ok, we just might over-approximate, but our code will still work).
Finally, we know 2 is the "oddest" prime - it happens to be the only even prime number. Because of this, we need only check 2 separately, then traverse odd numbers up to the square root of n. In the end, our code will resemble this:
//checks whether an int is prime or not.
boolean isPrime(int n) {
//check if n is a multiple of 2
if (n % 2 == 0) return false;
//if not, then just check the odds
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0)
return false;
}
return true;
}
As you can see, we've gone from checking every integer (up to n to find out that a number is prime) to just checking half of the integers up to the square root (the odd ones, really). This is a huge improvement, especially considering when numbers are large.
Here is a Simple Programme to Check Whether a Number is Prime or Not ;
import java.util.*;
class Example{
public static void main(String args[]){
Scanner input=new Scanner(System.in);
int count=0;
System.out.print("Input a Number : ");
int num=input.nextInt();
for(int i=2;i<num;i++){
if(num%i==0){count++;}
}
if(num>1&count==0){
System.out.print("\nIt Is a Prime Number.");
}
else{
System.out.print("\nIt Is a Not Prime Number.");
}
}
}
public static boolean isPrime(int n) {
if (n < 2) {
return false;
}
for (int i = 2; i < n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
I will suggest you to read #Neng Liu's answer from up to bottom and try to understand all the algorithms.
However, You can check this code for second algorithm from #Neng Liu's answer.
import java.util.Scanner;
public class PrimeNumber{
public static void main(String [] args){
int number,i,rem;
boolean flag = true;
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer to check if its PRIME number : ");
number = input.nextInt();
if(number >= 2){
for(i = 2; 2 * i < number; i++){
rem = number % i;
if(rem == 0){
flag = false;
break;
}
}
if(flag){
System.out.println(number+" is a Prime number");
}else{
System.out.println(number+" is not Prime number");
}
}else{
System.out.println("1 & Negative numbers can't be prime ! ");
}
}
}
So I'm trying to make a method that finds a random prime number from 0 to n(inputed from user) using the RandomGenerator class from the acm.utils package and for some reason it doesn't work! I've thought it through lots of times and I think this solution is right, bot it ends up giving numbers that are not wrong!
This is for a project at the uni and I have to use only acm.util! no scanners! only this kind of code
public int nextPrime(int n){
int num = rgen.nextInt(1, n);
boolean prime=false;
if (num==1){
return (num);
}else{
int i = 2;
int c = 0;
while ((i < num-1)&&(prime=false)){
if( (num % i) == 0){
c=c+1;
}
if((c==0)&&(i==(num-1))){
prime=true;
}
if(c>=1){
num = rgen.nextInt(1, n);
i=1;
}
i=i+1;
}
}
return (num);
}
= is for assignment and == is for comparison.
You need to change your condition
while ((i < num-1)&&(prime=false)){
to
while ((i < num-1)&&(prime==false)){ or
while ((i < num-1)&&(!prime)){
Here is a basic method to determine if a number is prime or not. This method is really only meant to understand the logic behind finding if a number is prime or not. Enjoy.
public boolean isPrime()
{
boolean prime = true;
for (int s = 2; s < original; s++)
if (original % s != 0 )
{
prime = true;
}
else
{
prime = false;
return prime;
}
return prime;
Your code is rather bizarre. Variable like c is not very clear, and the name doesnt help.
You could read other implementations.
I made some change to make it work. Traces help too !
public static int nextPrime(int n)
{
int num = (int)(1+Math.random()*n); // other generator
// TRACE HERE
System.out.println("START:"+num);
boolean prime=false;
// CHANGE HERE
if (num==2)
{
return (num);
}
else
{
int i = 2;
int c = 0;
// CHANGE HERE
while ((i < num-1)&&(prime==false))
{
// Not prime => next one
if( (num % i) == 0)
{
// TRACE HERE
System.out.println("YOU LOSE: :"+num+" divided by "+i);
c=c+1;
}
if((c==0)&&(i==(num-1)))
{
prime=true;
// TRACE HERE
System.out.println("BINGO:"+num);
// CHANGE HERE
break;
}
if(c>=1)
{
// SAME PLAYER LOOP AGAIN
num = (int)(1+Math.random()*n);
// TRACE HERE
System.out.println("RESTART:"+num);
i=1;
// CHANGE HERE
c=0;
}
i=i+1;
}
}
return (num);
}
Either you have misstated the problem or else you have not come close to coding the problem correctly. There are 4 prime numbers up to 10: {2,3,5,7}. If the user enters 10, should you give a random prime from this set, or a random one of the first 10 primes {2,3,5,7,11,13,17,19,23,29}? You said the problem was the first interpretation (where 11 would not be a valid response to 10) but you implemented an attempt at the second interpretation (where 11 would be a valid response to 10).
There is a simple way to generate a prime number uniformly within the primes in the range [1,1000000], say. Choose a random integer in the range and test whether it is prime. If so, return it. If not, repeat. This is called rejection sampling. It is quite complicated to get a uniformly random prime number without rejection sampling, since it's not easy to count or list the prime numbers in a large range. It is relatively easy to test whether a number is prime, and for n>1 it only takes about log n samples on average to find a prime in [1,n].
Having trouble understanding what's wrong in the code.
I'm also trying to avoid using multiple methods if possible and just keep the functionality within the while loop.
public class NthPrime {
public static void main(String[] args) {
int n;
System.out.println("Which nth prime number do you want?");
n = IO.readInt();
if(n <= 0) {
IO.reportBadInput();
return;
}
if(n == 1) {
System.out.println("Nth prime number is: 2");
return;
}
int primeCounter = 1;
int currentNum = 3;
int primeVal = 0;
while(primeCounter < n) {
for(int x = 2; x < currentNum; x++) {
if(currentNum % x == 0) {
continue;
} else {
primeVal = currentNum;
primeCounter++;
}
}
currentNum++;
}
System.out.println(primeVal);
}
}
Your code assumes that every time it encounters a number coprime to the number it's checking, it has a prime. That is to say, your if block:
if(currentNum % x == 0) {
continue;
} else {
primeVal = currentNum;
primeCounter++;
}
says "If it's composite (i.e. divisble by x), then there's no point in continuing to test this number. However, if it's not composite, then we have a prime!" This is faulty because if there's a composite number above the coprime number, your code doesn't care.
This faulty test also gets run for every single coprime number below the number you're checking.
You may be able to fix this by moving the code that updates primeVal and increments primeCounter to the place where you're certain that currentNum is prime. This would be after the for loop is done checking all the numbers below currentNum.
General hint: Speed up your code by looping to the square root of currentNum, not currentNum itself. It's equivalent to what you have now, but faster.
I am practicing past exam papers for a basic java exam, and I am finding it difficult to make a for loop work for testing whether a number is prime. I don't want to complicate it by adding efficiency measures for larger numbers, just something that would at least work for 2 digit numbers.
At the moment it always returns false even if n IS a prime number.
I think my problem is that I am getting something wrong with the for loop itself and where to put the "return true;" and "return false;"... I'm sure it's a really basic mistake I'm making...
public boolean isPrime(int n) {
int i;
for (i = 2; i <= n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
The reason I couldn't find help elsewhere on stackoverflow is because similar questions were asking for a more complicated implementation to have a more efficient way of doing it.
Your for loop has a little problem. It should be: -
for (i = 2; i < n; i++) // replace `i <= n` with `i < n`
Of course you don't want to check the remainder when n is divided by n. It will always give you 1.
In fact, you can even reduce the number of iterations by changing the condition to: - i <= n / 2. Since n can't be divided by a number greater than n / 2, except when we consider n, which we don't have to consider at all.
So, you can change your for loop to: -
for (i = 2; i <= n / 2; i++)
You can stop much earlier and skip through the loop faster with:
public boolean isPrime(long n) {
// fast even test.
if(n > 2 && (n & 1) == 0)
return false;
// only odd factors need to be tested up to n^0.5
for(int i = 3; i * i <= n; i += 2)
if (n % i == 0)
return false;
return true;
}
Error is i<=n
for (i = 2; i<n; i++){
You should write i < n, because the last iteration step will give you true.
public class PrimeNumberCheck {
private static int maxNumberToCheck = 100;
public PrimeNumberCheck() {
}
public static void main(String[] args) {
PrimeNumberCheck primeNumberCheck = new PrimeNumberCheck();
for(int ii=0;ii < maxNumberToCheck; ii++) {
boolean isPrimeNumber = primeNumberCheck.isPrime(ii);
System.out.println(ii + " is " + (isPrimeNumber == true ? "prime." : "not prime."));
}
}
private boolean isPrime(int numberToCheck) {
boolean isPrime = true;
if(numberToCheck < 2) {
isPrime = false;
}
for(int ii=2;ii<numberToCheck;ii++) {
if(numberToCheck%ii == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
}
With this code number divisible by 3 will be skipped the for loop code initialization.
For loop iteration will also skip multiples of 3.
private static boolean isPrime(int n) {
if ((n > 2 && (n & 1) == 0) // check is it even
|| n <= 1 //check for -ve
|| (n > 3 && (n % 3 == 0))) { //check for 3 divisiable
return false;
}
int maxLookup = (int) Math.sqrt(n);
for (int i = 3; (i+2) <= maxLookup; i = i + 6) {
if (n % (i+2) == 0 || n % (i+4) == 0) {
return false;
}
}
return true;
}
You could also use some simple Math property for this in your for loop.
A number 'n' will be a prime number if and only if it is divisible by itself or 1.
If a number is not a prime number it will have two factors:
n = a * b
you can use the for loop to check till sqrt of the number 'n' instead of going all the way to 'n'. As in if 'a' and 'b' both are greater than the sqrt of the number 'n', a*b would be greater than 'n'. So at least one of the factors must be less than or equal to the square root.
so your loop would be something like below:
for(int i=2; i<=Math.sqrt(n); i++)
By doing this you would drastically reduce the run time complexity of the code.
I think it would come down to O(n/2).
One of the fastest way is looping only till the square root of n.
private static boolean isPrime(int n){
int square = (int)Math.ceil((Math.sqrt(n)));//find the square root
HashSet<Integer> nos = new HashSet<>();
for(int i=1;i<=square;i++){
if(n%i==0){
if(n/i==i){
nos.add(i);
}else{
nos.add(i);
int rem = n/i;
nos.add(rem);
}
}
}
return nos.size()==2;//if contains 1 and n then prime
}
You are checking i<=n.So when i==n, you will get 0 only and it will return false always.Try i<=(n/2).No need to check until i<n.
The mentioned above algorithm treats 1 as prime though it is not.
Hence here is the solution.
static boolean isPrime(int n) {
int perfect_modulo = 0;
boolean prime = false;
for ( int i = 1; i <= n; i++ ) {
if ( n % i == 0 ) {
perfect_modulo += 1;
}
}
if ( perfect_modulo == 2 ) {
prime = true;
}
return prime;
}
Doing it the Java 8 way is nicer and cleaner
private static boolean isPrimeA(final int number) {
return IntStream
.rangeClosed(2, number/2)
.noneMatch(i -> number%i == 0);
}