sorry for the "fix my code" post
EDIT: related more to syntax of a for loop than prime numbers, also solved now.
My task is to take an int from the console and print out (on separate lines) all the prime numbers from 1 to n inclusive.
My method starts at n, checks if its prime, then increments n down by one and loops until n=2.
To check if a number is prime I run a loop, checking is the remainder of diving the number by x is equal to zero, with x starting at 2 and stopping at root(n).
Now this all works in theory, and reading my code I don't see where it goes wrong.
public class Prime {
public static boolean isPrime(int n) {
boolean result = true;
for (int x = 2; x>=sqrt(n); x++) {
if ((n % x) == 0) {
result = false;
break;
} else {
x++;
}
}
return result;
}
public static void main(String[] args) {
Scanner intIn = new Scanner(System.in);
int i = intIn.nextInt();
while (i>=2) {
if (isPrime(i)) {
System.out.println(i);
i--;
} else {
i--;
}
}
}
}
For example an input of 10 will return 10 (along with 9,8,7,6,5,3), even though isPrime() checks if 10 % 2 == 0, then sets result to false.
What am I missing here??
Again I apologise for the annoying (slightly duplicate) question.
The condition in the for loop is the condition to continue the loop, not the condition to stop it. You need to replace >= with <=:
for (int x = 2; x<=sqrt(n); x++) {
// Here -----^
You are incrementing x twice, and the loop's condition should be x<=sqrt(n) :
for (int x = 2; x>=sqrt(n); x++) { // here
if ((n % x) == 0) {
result = false;
break;
} else {
x++; // and here
}
}
The correct logic should be:
public static boolean isPrime(int n) {
for (int x = 2; x<=sqrt(n); x++) {
if ((n % x) == 0) {
return false;
}
}
return true;
}
In the loop x must be less than or equal to
So change the expression for (int x = 2; x>=sqrt(n); x++) to
for (int x = 2; x<=sqrt(n); x++)
Try it this way, it's much clearer and concise.
public static boolean isPrime(int candidate) {
int candidateRoot = (int) Math.sqrt((double) candidate);
return IntStream.rangeClosed(2, candidateRoot)
.noneMatch(i -> candidate % i == 0); // return true if the candidate
// isn't divisible for any of the
// numbers in the stream
}
public static void main(String[] args) {
Scanner intIn = new Scanner(System.in);
int i = intIn.nextInt();
List<Integer> primeList = IntStream.rangeClosed(2, i)
.filter(candidate -> isPrime(candidate))
.boxed()
.collect(toList());
System.out.println(primeList);
// Another way
Map<Boolean, List<Integer>> primeAndNotPrimeMap = IntStream.rangeClosed(2, i)
.boxed()
.collect(partitioningBy(candidate -> isPrime(candidate)));
System.out.println(primeAndNotPrimeMap);
}
Related
I am struggling to understand why code wouldn't work. According to the truth table/logic gates for AND and OR https://en.wikipedia.org/wiki/Truth_table I would assume that I would be able to have an if statement inside the for-loop such that (p < 2 || p % i == 0) would work for finding prime numbers but it fails when considering negative numbers.
I know that if you if take out the p < 2 and write it as an if statement outside this for-loop it works, but if the p < 2 is inside the for-loop it does not work. Why is this so?
public class test {
public static void main(String [] args) {
System.out.println("Hello World!");
int a = 7;
System.out.println("A is Prime: " + isPrime(a));
System.out.println();
int b = 4;
System.out.println("B is Prime: " + isPrime(b));
System.out.println();
int c = -7;
System.out.println("C is Prime: " + isPrime(c));
System.out.println();
int d = 53;
System.out.println("D is Prime: " + isPrime(d));
}
public static boolean isPrime(int p) {
for (int i = 2; i < p; i++) {
if (p < 2 || p % i == 0) {
return false;
}
}
return true;
}
}
Because for p < 2, the body of the for loop is never performed. Indeed:
for (int i = 2; i < p; i++) {
// ...
}
If p = 2, then it initializes i = 2, and then checks i < p which fails, and hence the body is never executed. It skips the for loop, and thus returns true.
We can fix it by performing a check before (or after) the for loop, and even boost the performance of the loop slighly:
public static boolean isPrime(int p) {
if(p <= 2) {
return p == 2;
}
if(p % 2 == 0) {
return false;
}
for (int i = 3; i*i <= p; i += 2) {
if (p % i == 0) {
return false;
}
}
return true;
}
We can simply return false first for all values less than 2, and true for 2. Furthermore we only need to iterate up to √p, since if there is a value j larger than √p that divides p, then there is a smaller value i = p/j that is smaller than √p that will already be checked. We furthermore only need to check odd numbers, since even numbers are already implied by the division by 2.
You may want to invest in Math.abs(int):
public static boolean isPrime(int p) {
p = Math.abs(p);
for (int i = 2; i < p; i++) {
...
This will ensure that p is always non-negative, and your initial assumptions about how the loop should behave are justified.
I have to write a boolean method that checks if a number n is a circular prime, using only integer computations, so no Strings. I wrote two other methods that have to be included.
boolean isPrime(int n) {
if (n < 1) {
return false;
} else if (n == 1 || n == 2) {
return true;
} else if (n % 2 != 0) {
for (int i = 3; i < n; i+=2) {
if (n % i == 0) {
return false;
}
}
return true;
} else {
return false;
}
}
This checks if the number is a prime.
int largestPowerOfTen(int n) {
for (int i = 1; i < n * 10; i*=10) {
if (n / i == 0) {
return i / 10;
}
}
return 1;
}
This returns the largest power of ten of the number. For instance, 23 would return 10, 704 would return 100, etc.
I had the idea to put every digit into an array and move the digits around from there, but I'm stuck at the moving part.
boolean isCircularPrime(int n) {
ArrayList<Integer> k = new ArrayList<Integer>();
int i = 0;
while (n != 0) {
k.add(n % 10);
n /= 10;
i++;
}
//???
}
So how do I move the digits around?
Assuming a "circular prime number" is a number that is a prime number for all rotations of the digits...
You can't just rotate the number, because zeroes won't be conserved.
First break up the number into an array - each digit of the number an element of the array. Use n % 10 to find the last digit, then n /= 10 until n == 0.
Create a method the generates a number from the array with a specified starting index. This is the crux of the problem, and here's some code:
private static int generate(int[] digits, int index) {
int result = 0;
for (int i = 0; i < digits.length; i++) {
result = result * 10 + digits[(index + i) % digits.length];
}
return result;
}
Then loop over every possible starting index for your digits and check if it's prime.
The remaining code I leave to the reader...
import java.util.Scanner;
class CircularPrime
{
public boolean prime(int n)
{
int lim=n,count=0;
for(int i=1;i<=lim;i++)
{
if(n%i==0)count++;
}
if(count==2)
return true;
else
return false;
}
public int circlize(int n)
{
int len,x,y,circle;
len=(""+n).length();
x=n/(int)Math.pow(10,len-1);
y=n%(int)Math.pow(10,len-1);
circle=(y*10)+x;
return circle;
/**
Another way using String
String str = Integer.toString(n);
String arr = str.substring(1)+str.charAt(0);
int a = Integer.parseInt(arr);
return a;
**/
}
public void check(int n)
{
int a=n;
boolean flag=true;
System.out.println("OUTPUT:");
do
{
if(!(prime(a)))
{
flag=false;
break;
}
a=circlize(a);
System.out.println(a);
}while(a!=n);
if(flag)System.out.println(n+" IS A CIRCULAR PRIME");
else System.out.println(n+" IS NOT A CIRCULAR PRIME");
}
public static void main(String ar[])
{
CircularPrime obj = new CircularPrime();
Scanner sc = new Scanner(System.in);
System.out.print("Enter a number: ");
int n=sc.nextInt();
obj.check(n);
}
}
I need to create a program that can get all the prime numbers from 1 to a large number. I have a getPrime method which returns true if the number is prime or false if it is not prime. When I use this method and a while loop to get a list of prime numbers from 1 to a large number it keeps returning 24 then 4 then 5.the variable end, in code below is asked for in a prime class runner separately. Here is my code:
public class Prime
{
private long userNumber;
private int numRoot;
private int x;
private boolean isPrime;
private int factors;
private long end;
private int i;
public void setUserNumber(long num)
{
userNumber = num;
}
public void setEndNumber(long n)
{
end = n;
}
public boolean getPrime()
{
numRoot = ((int)Math.sqrt(userNumber));
for (x=2; x<=numRoot; x++)
{
if ((userNumber % x) == 0)
{
factors++;
}
}
if (factors >1) {
isPrime = false;
}
else {
isPrime = true;
}
return isPrime;
}
public void getPrimeList()
{
if(end < 2) {
System.out.println("No prime numbers");
System.exit(0);
}
System.out.printf("\nThe prime numbers from 1 to %d are: \n 2", end);
Prime primeNum = new Prime();
i = 3;
while( i <= end )
{
userNumber = i;
getPrime();
if (isPrime == true)
{
System.out.println(userNumber);
}
i++;
}
System.out.println();
}
}
public void getPrimes(int N) {
for (int i = 2; i <= N; i++) {
if (isPrime(i)) System.out.println(i);
}
System.out.println("These are all the prime numbers less than or equal to N.");
}
private boolean isPrime(int N) {
if (N < 2) return false;
for (int i = 2; i <= Math.sqrt(N); i++) {
if (N % i == 0) return false;
}
return true;
}
The code below is written in C#, although it will work in Java with very little modification.
I use a long as the data type as you haven't been specific when you say "a large number".
public static bool isPrime(long Number)
{
if (Number == 1) { return false; }
int i = 2;
while (i < Number)
{
if (Number % i++ == 0) { return false; }
}
return true;
}
It can be applied like so, again this is C#, but will work in Java with little modification.
while (i <= LARGE_NUMBER)
{
Console.Write((isPrime(i) ? i.ToString() + "\n" : ""));
i++;
}
public class PrimeTest{
private static final int MAX_NUM = Integer.MAX_VALUE; // your big number
public static void main(String[] args) {
int count = 0;
for(int i=0; i<MAX_NUM; i++) {
if (isPrime(i)) {
System.out.printf("Prime number %d\n", i);
count++;
}
}
System.out.printf("There is %d prime numbers between %d and %d\n", count, 0, MAX_NUM);
}
public static boolean isPrime(int number) {
if (number < 2) {
return false;
}
for (int i=2; i*i <= number; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
}
A prime number p should have zero factors between 2 and sqrt(p), but you are allowing one here:
if (factors >1){
isPrime = false;
}
In fact, there's no need to count factors at all, you can directly do
if ((userNumber % x) == 0) {
return false;
}
If you however need to count factors anyways, I would suggest setting factors explicitly to 0 at the start. It's not a good practice to rely on implicit initial values.
The problem is that you're using too many instance variables inside getPrime, causing you to unintentionally inherit state from previous iterations. More precisely, factors should be reset to 0 at the start of getPrime.
A better way to go about this is by making x, numRoot, isPrime and factors local variables of getPrime:
public boolean getPrime()
{
int factors = 0;
boolean isPrime;
int numRoot = ((int) Math.sqrt(userNumber));
for (int x=2; x<=numRoot; x++)
{
if ((userNumber % x) == 0)
{
factors++;
}
}
if (factors >1){
isPrime = false;
} else {
isPrime = true;
}
return isPrime;
}
You can go even further and make userNumber an argument of getPrime:
public boolean getPrime(int userNumber)
{
// ...
and call it with:
while( i <= end )
{
isPrime = getPrime(i);
if (isPrime)
{
System.out.println(userNumber);
}
i++;
}
Two things to note:
I removed the usage of userNumber inside getPrimeList completely, I simply use i instead.
The isPrime could be removed as well if it's not needed elsewhere, simply use if(getPrime(i)) { ... } instead.
Your algorithm is the wrong solution for your task. The task is to find all primes from 2 to N, the appropriate algorithm is the Sieve of Eratosthenes. (See here for an epic rant discussing basics and optimizations of sieve algorithms.)
It is known that all primes are either 2,3,5,7,11,13 or of the form
30*k-13, 30*k-11, 30*k-7, 30*k-1, 30*k+1, 30*k+7, 30*k+11, 30*k+13,
for k=1,2,3,...
So you generate an array boolean isPrime[N+1], set all to true and for any candidate prime p of the form above, until pp>N and if isPrime[p] is true, set all isPrime[kp]=false for k=2,3,4,...N/p.
int N;
Boolean isPrime[] = new Boolean[N+6];
static void cross_out(int p) {
for(int k=5*p, d=2; k<N; k+=d*p, d=6-d) {
isPrime[k]=false;
}
}
static void sieve() {
for(int k=0; k<N; k+=6) {
isPrime[k ]=isPrime[k+2]=false;
isPrime[k+3]=isPrime[k+4]=false;
isPrime[k+1]=isPrime[k+5]=true;
}
for(int k=5, d=2; k*k<N; k+=d; d=6-d) {
if(isPrime[k]) cross_out(k);
}
}
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;
}
}
}
}
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;
}
}