Potentially simple math - Prime Number Code - java

I'm having some trouble getting my head around this program that's used an example in a guide book. It might be more of a math question than a coding question. Edited to include code!
// Find prime numbers between 2 and 100.
class Prime {
public static void main(String args[]) {
int x, y;
boolean isprime;
for(x=2; x < 100; x++) {
isprime = true;
for(y=2; y <= x/y; y++)
if((x%y) == 0) isprime = false;
if(isprime)
System.out.println(x + " is a prime number.");
}
}
}
Here's my understanding of the program:
Declare x (potential prime number) and y (a number to divide x by - if there is a division possible [other than by itself or 1] that yields no remainder, it's not a prime).
Declare a boolean value to hold whether the number is prime.
Create a for loop to test each and every number between 2 and 100
Default isprime boolean to true
Create a for loop to divide the prime by numbers between 2 and ??? (I don't understand the condition part of this for loop)
I tried to put in a system.out.print option here to show what x and y were at each iteration, but it then calculated non-prime numbers as prime numbers.
If you divide the prime by all these numbers and there is a number without a remainder, change boolean isprime to false.
If, after going through all values and all of them had a remainder, print that this is a prime number.

Its skipping numbers that do not make sense to check to see if they are factors. For example, if x = 49, it will check till y = 7 after which the condition will be false. Since it has already checked for all the numbers before 7, a higher factor is not possible that the square root of the number. So essentially, it checks for factors from 2 to square root of the number.

Related

I don't understand this 'for' loop for prime number validation in Java

I don't understand this 'for' loop in Java
This loop is just to check if a number is prime or not. I understand the first statement because 1 is not a prime number but it's what happens in the 'for' statement. Why is 'primeNumber' being divided by two and why is the second 'if' calculating for a remainder of zero? how does this code help to confirm a prime number? what is it doing?
public static boolean isPrime (int primeNumber) {
if (primeNumber == 1) {
return false;
}
for (int primeDivider=2; primeDivider <= primeNumber/2; primeDivider++) {
if (primeNumber % primeDivider == 0) {
return false;
}
}
return true;
}
A prime number can only be divided by itself and one. 7 is prime because only 1 and 7 divide into 7. Also 8 is not prime because as well as 1 and 8, both 2 and 4 divide into 8.
Look at the for loop and see what values primeDivider takes: 2, 3, 4, 5, ... The loop tries each of these in turn to see if it divides into the number you are testing. If it divides evenly, with a remainder 0, then the number being tested is not prime and the method returns false. If none of the numbers divide, then the number being tested in prime and the method returns true. As an aside, primeNumber is a bad variable name. Something like possiblePrime would be better. The number being tested might not be prime.
The primeDivider sequence stops at half the number being tested. If a number is not prime (a composite number) then at least one of its divisors is guaranteed to be less than or equal to half the number.
As others have said, this is not a very efficient test. Here is a slightly more efficient version for you to study:
public static boolean isPrime (int possiblePrime) {
// Test negatives, zero and 1.
if (possiblePrime <= 1) {
return false;
}
// Test even numbers
if (possiblePrime % 2 == 0) {
// 2 is the only even prime.
return possiblePrime == 2;
}
// Test odd numbers >= 3.
int limit = possiblePrime / 2;
for (int primeDivider = 3; primeDivider <= limit; primeDivider += 2) {
if (possiblePrime % primeDivider == 0) {
return false;
}
}
// Only prime numbers reach this point.
return true;
}
By treating odd and even numbers separately, you can catch all the even numbers with a single test and by stepping primeDivider by 2 each time, roughly halve the time taken for odd numbers.
As billjamesdev says, that can be made even more efficient by using:
int limit = (int)Math.floor( Math.sqrt( possiblePrime ));
A composite number will always have a divisor, other than 1, less than or equal to its square root.

Complexity of print first n prime number

In an interview I was given this questions:
Write a function to print first n prime numbers
The function looks like this:
Live on ideone
while (true) {
boolean isPrime = true;
for (int divisor = 2; divisor <= (int)(Math.sqrt(number)); divisor++) {
if (number % divisor == 0) {
isPrime = false;
break;
}
}
number++;
if(isPrime) {
System.out.print(number + " ");
primes++;
}
if (primes == n)
break;
}
A simple complexity analysis could led to O(n√n)
But the interviewer said that the outerloop doesn't go to simply n because for example to find the first 100 prime numbers we need to loop to 541 (that is the 100th prime numbers)
So how do we express the time complexity given this?
Answering this takes high math, namely the distribution law of the prime numbers. It tells you (https://en.wikipedia.org/wiki/Prime_number_theorem) that the value of the n-th prime number is about n.log(n).
Then your complexity is O(n√n.log(n)√log(n)).
I may turn out that this bound is pessimistic, because not all iterations run until √n. For instance, even numbers are detected immediately. For a tighter bound, you would need the distribution law of the smallest factor of the integers.

I do not understand the logic behind this prime number checker (Java)

I do not understand the logic behind this number checker and I'm wondering if somebody could help me understand it a little bit better.
Here's the code:
I will do my best to comment on what's happening but I do not fully understand it.
//find prime numbers between 2 and 100
class PrimeNumberFinder {
public static void main(String args[]) {
int i, j; // declare the integer variables "i" and "j"
boolean isPrime; // declare the Boolean variable is prime but do not assign value
// create a for loop that starts at two and stops at 99.
for (i=2; i < 100 ; i++) {
isPrime = true; // I do not know why isPrime is set to true here.
// This is where I get confused badly.. we give the "j" variable a value of two and check to see if it's less than whatever "i" divided by "j" is.
// If "i=2" then how would j (which is = 2) be less than or equal to i/j (2/2)?
for (j = 2; j <= i/j; j++)
if ((i%j) == 0) isPrime = false; // If a certain number goes in evenly that isn't 1, or "i" itself, it isn't prime so we set the boolean to false
if (isPrime) // if true print i
System.out.println(i + " Is a prime number");
}
}
}
As you can see the second for loop and almost everything going on within it confuses me, especially the "j <= i/j" because to me j is always going to be bigger.. and why is "j" even increasing? Can't you just divide it by two and determine whether or not it's prime that way?
Any help is greatly appreciated, thank you for reading.
Let's go through it line by line.
int i, j;
boolean isPrime;
We start with declaring our variables. Nothing too fancy.
for (i=2; i < 100; i++) {
isPrime = true;
Here we enter our loop that basically contains all the number we are going to check (here: 2 - 99). We also state that the current number is a prime number (unless proven otherwise).
for (j = 2; j <= i/j; j++)
if ((i%j) == 0) isPrime = false;
Now here is where the magic happens. We are going to check if we can divide the current number i evenly by any integer ranging from j == 2 to i/j (i/j ultimately is just a fancy way of writing Math.sqrt(i)). So why up until there?
Well, say we have two divisors a and b such that a * b = i. Now, if divisor a is bigger than the square root of i, then the other divisor b will be smaller than the square root of i. If not then a * b > i and this isn't possible.
So, if we can find a case in which we can divide evenly, this explicitly means that the current number is not prime and we set the isPrime variable to false.
if (isPrime) // if true print i
System.out.println(i + " Is a prime number");
}
So, if we still have isPrime == true, it means that the current number withstood our test and we can print it.
Two further improvements;
Once we know the number is not prime, there is no need to check any
additional divisors, so we want to exit the loop and hence a
break; statement could be addded.
2 is the only even prime number, so alternatively you could
start the second loop at j == 3 and increase by 2 after every execution.
You'll then have to consider the case when i == 2 separately.

Russian Doll Primes

This question was asked in an interview (about prime numbers)
Russian Doll Primes
They are more commonly known as Truncatable Primes.
I found this code on wiki
public static void main(String[] args){
final int MAX = 1000000;
//Sieve of Eratosthenes (using BitSet only for odd numbers)
BitSet primeList = new BitSet(MAX>>1);
primeList.set(0,primeList.size(),true);
int sqroot = (int) Math.sqrt(MAX);
primeList.clear(0);
for(int num = 3; num <= sqroot; num+=2)
{
if( primeList.get(num >> 1) )
{
int inc = num << 1;
for(int factor = num * num; factor < MAX; factor += inc)
{
//if( ((factor) & 1) == 1)
//{
primeList.clear(factor >> 1);
//}
}
}
}
//Find Largest Truncatable Prime. (so we start from 1000000 - 1
int rightTrunc = -1, leftTrunc = -1;
for(int prime = (MAX - 1) | 1; prime >= 3; prime -= 2)
{
if(primeList.get(prime>>1))
{
//Already found Right Truncatable Prime?
if(rightTrunc == -1)
{
int right = prime;
while(right > 0 && primeList.get(right >> 1)) right /= 10;
if(right == 0) rightTrunc = prime;
}
//Already found Left Truncatable Prime?
if(leftTrunc == -1 )
{
//Left Truncation
String left = Integer.toString(prime);
if(!left.contains("0"))
{
while( left.length() > 0 ){
int iLeft = Integer.parseInt(left);
if(!primeList.get( iLeft >> 1)) break;
left = left.substring(1);
}
if(left.length() == 0) leftTrunc = prime;
}
}
if(leftTrunc != -1 && rightTrunc != -1) //Found both? then Stop loop
{
break;
}
}
}
System.out.println("Left Truncatable : " + leftTrunc);
System.out.println("Right Truncatable : " + rightTrunc);
}
This gives the output:
Left Truncatable : 998443
Right Truncatable : 796339
But I am not able to solve this particular Russian doll prime number problem like if you have a prime number and you remove either left or right digit of this prime number then if that resulting number is prime number or not?
I am new to this so please pardon any mistake.
Let's start from the beginning:
According to the link you supplied with your question:
"Russian Doll Primes are
prime numbers whose right digit can be repeatedly removed, and are
still prime."
I will assume that you have a function boolean isPrime(int) to find out if a number is prime.
Googling, we will find from Wikipedia that the number of right-truncatable prime numbers up to 73,939,133 is 83, which makes brute-force a viable option; but a few optimization techniques can be employed here:
Since we right-truncate, we can safely eliminate even numbers (since any even number won't be prime, and so any number generated upon it will never be a russian doll prime).
Since any number that starts with 5 is divisible by 5, then based on the same rule I mentioned in the previous point, we can eliminate 5.
That leaves us with numbers that contain 1, 3, 7, and 9.
Now if we wanted to generate all possible combinations of these 4 numbers that do not exceed the maximum you mentioned (1,000,000), it would take only 4,096 iterations.
The downside of this technique is that we now have 4,096 numbers that contain possible non-prime numbers, or prime numbers that are formed from non-prime numbers and hence are not russian doll primes. We can eliminate these numbers by looping through them and checking; or better yet, we can examine russian doll primes more closely.
Upon examining the rule I quoted from your link above, we find that a russian doll primes are prime numbers whose right digit can be repeatedly removed, and are still prime (and hence are still russian doll prime, given the word repeatedly)!
That means we can work from the smallest single-digit russian doll primes, work our generation magic that we used above, and since any prime number that is formed from russian doll prime numbers is a russian doll prime number, we can eliminate non-primes early on, resulting in a clean list of russian doll prime numbers, while reducing the running time of such a program dramatically.
Take a look at the generation code below:
void russianDollPrimesGeneration(int x) {
x *= 10;
if (x * 10 >= 1000000) return;
int j;
for (int i=1; i<=9; i+=2) {
if (i == 5) continue;
j = x + i;
if (isPrime(j)) {
addToRussianDollPrimesList(j);
russianDollPrimesGeneration(j);
}
}
}
Provided that void addToRussianDollPrimesList(int x) is a function that adds x to a list that we previously preserved to store the russian doll prime numbers.
UPDATED NOTE
Note that you can put the call to void russianDollPrimesGeneration(int x) that we made inside the if condition inside the void addToRussianDollPrimesList(int x) function, because whenever we call the former function, we will always call the latter function with the same arguments. I'm separating them here to emphasize the recursive nature of the generation function.
Also note that you must run this function with the integer 0.
A final note is that there are a number of cases that the generation function void russianDollPrimesGeneration(int x) above won't count, even though they are Russian Doll Primes.
Remember when we omitted 2 and 5, because even numbers and numbers divided by 5 cannot be primes and so cannot be Russian Doll Primes? and consequently cannot form Russian Doll Primes? Well, that case does not apply to 2 and 5, because they are prime, and since they are single digits, therefore they are Russian Doll Primes, and are eligible to form Russian Doll Primes, if placed in the left-side, like 23 and 53.
So how to correct our code to include these special cases?
We can make a wrapper function that adds these two numbers and checks for Russian Doll Primes that can be formed using them (which will be the same generation function we are using above).
void generationWrapperFunction(int x) {
addToRussianDollPrimesList(2);
russianDollPrimesGeneration(2);
addToRussianDollPrimesList(5);
russianDollPrimesGeneration(5);
russianDollPrimesGeneration(0);
}
END UPDATED NOTE
This little function will produce a list of russian doll prime numbers, which can then be searched for the number we are looking for.
An alternative, yet I believe will be more time-consuming, is the following recursive function:
boolean isRussianDollPrime(int n) {
if (!isPrime(n)) return false;
if (n < 10) return true;
return isRussianDollPrime(n / 10);
}
This function can be modified to work with left-truncatable primes. The generation-based solution, however, will be much difficult to implement for left-truncatable primes.
Your problem is to use this code or to solve the problem ?
if to solve it you can generate primes using Sieve algorithm then check if the element is prime or not (if it was prime then check if element/10 is also prime)
Let's start with a simple assumption that we know how to write code to detect if a value is a prime. In a coding interview, they won't likely won't expect you to pull out "Sieve of Eratosthenes". You should start with simple code that handles the special cases of x<=1 (false) and x==2(true). Then check for an even number !(x % 2)(false). Then loop on i from 3..sqrt(x) (incrementing by +2 each time) to see if there's an odd number divisor for x.
boolean isPrime(long x)
{
// your code goes here
}
And once we have a function to tell us if a value is prime, we can easily build the function to detect if a value is a Russian Prime. Therefore we just need to loop on our value, each time check for prime, and then chop off the right hand side. And the easiest way to remove the right-most digit from a number is to simply divide it by 10.
boolean isRussianPrime(long x)
{
boolean result = isPrime(x);
while ((x != 0) && result)
{
// chop off the right digit of x
x = x / 10;
if (x != 0)
{
result = isPrime(x);
}
}
return result;
}
And that's really all there is to it.
package com.example.tests;
public class RussianDollPrimeNumber {
public static void main(String[] args) {
int x= 373;
int k;
int n =x;
for ( k= String.valueOf(x).length()-1;k>0;k--){
System.out.println(n);
if (isPrime(n)){
String m=String.valueOf(n).substring(0, k);
n=Integer.parseInt(m);
continue;
}else {
break;
}
}
if( k==0){
System.out.println("Number is Russianl Doll Number "+x);
}else {
System.out.println("Number is not Russianl Doll Number "+x);
}
}
private static boolean isPrime(int x) {
boolean check=true;
for (int i=2;i<x/2;i++){
if( (x%i)==0){
check=false;
}
}
return check;
}
}

Optimize calculation of prime numbers [duplicate]

This question already has answers here:
Project Euler 3 - Highest Prime Factor
(2 answers)
Project Euler #3 takes forever in Java
(9 answers)
Closed 9 years ago.
I am trying Problem 3 from Project Euler and my algorithm is far too slow. Does anyone know how to optimize this? The number I am trying to calculate up to is 600851475143L. It takes forever to calculate this so I need a way to speed up the calculations.
LOGIC:
Go through all the numbers from 3 until that number-1
For each of these numbers check if they are prime by dividing them by all the numbers in between and if they dont divide by any of them then they are prime.
If prime then add them to an array.
public static void problem3(long number){
long number2 = number;
long sqrtNumber = (long)Math.sqrt(number2);
int indexNum = 1;
boolean isPrime = false;
int primeNums[] = new int[2];
primeNums[0] = 2;
//puts prime numbers into an array
for(int y = 3; y < sqrtNumber; y++){
isPrime=true;
for(int theNum = 2; theNum < y; theNum++){
//if y divides evenly by any number then it is not prime
if(y%theNum==0){
//dont store in array
isPrime=false;
break;
}
}
if(isPrime == true){
//add to array
System.out.println(y);
//put y in the array and exapnd the array
//System.out.println("y: " + y);
primeNums[indexNum] = y;
int[] newArray = new int[primeNums.length + 1];
System.arraycopy(primeNums, 0, newArray, 0, primeNums.length);
primeNums = newArray;
indexNum++;
}
}
********** UPDATE **************
I calculated up to the square root which sped up the calculations a lot but I also done something else which was to add a break statement in the forloop to break once I discovered the number was not prime. I edited the code above to reflect these changes.
My algorithm is still wrong for calculating the prime factors though so I will need to have a look at it and maybe raise a new question.
You don't have to divide by every number. You only have to divide by each prime number between 2 and the square root of your number.
The first thing you can do is only test possible factors up through the square root of the number that you're testing, because if you find a factor greater than the square root, then you should have found a factor less than the square root.
If you need additional performance, then use the Sieve of Eratosthenes. That allows you to use the results of previous primes to cut down the work on determining if larger numbers are prime.

Categories