Prime numbers finder - java

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].

Related

Java throwing division by zero error?

In an attempt to relearn how to write code in Java I've been going through some problems from Project Euler. The following code I've written is to solve problem 3: finding the largest prime factor of the number 600851475143.
public class ProjectEuler {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
ProjectEuler t = new ProjectEuler();
System.out.println(t.findLargestPrime(600851475143L));
}
public Boolean isPrime(int x) {
Boolean answer = true;
for (int i = 2; i < x/2; i++) {
if (x%i == 0) {
answer = false;
}
}
return answer;
}
public int findLargestPrime(Long max) {
int largest = 1;
for (int i = 2 ; i < max/2; i++) {
if (max%i == 0 && isPrime(i) && i > largest) {
largest = i;
}
}
return largest;
}
}
However, when I run it the code throws an arithmetic error because I'm trying to divide by zero? The actual error message is shown here:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at projecteuler.ProjectEuler.findLargestPrime(ProjectEuler.java:37)
at projecteuler.ProjectEuler.main(ProjectEuler.java:19)
I don't know if I've made a stupid mistake somewhere or if it's a quirk of Java that I don't understand? Could anyone shed some light on this?
Thank you.
for (int i = 2 ; i < max/2; i++) will eventually overflow (because 600851475143 / 2 is bigger than Integer.MAX_VALUE) and eventually i will equal to 0 when it will happen max%i will throw that exception.
Change i to long if you want to prevent it from happeninng (you should also change all the other int's to long).
This is not an answer to the actual question, but: You do not have to check all the numbers up to max, and you do not even have to do any checks whether a divisor is prime. You just have to (repeatedly) divide the max by any divisor i you found.
long l = 600851475143L;
for (int i = 2; i <= Math.sqrt(l); i++) {
if (l % i == 0) {
System.out.println(i);
l /= i;
i--;
}
}
System.out.println("--> " + l);
This way, you know that this divisor must be prime -- if it were composite, max would already have been divided by its components. This also means that you do not have to loop all the way up to max (which, for the given value, would take a really long time), but only up to the largest prime divisor, which might be much much smaller. And once you reach sqrt(l) -- for the current value of l, not the original! -- you can stop, since there can not be any divisors higher than that, and the remaining value of l will be the final (and thus, largest) prime factor.
Thus, this reduces the complexity from about O(n²) to about O(n½).

Prime Number Program Problems

I'm currently working on a program in which the user inputs a number, and the program will give you the number of prime numbers up to that number. Although there are no errors, the program always outputs the same number: 3. This is the code:
public static int Prime(int num){
boolean isPrime = true;
int count = 0;
for (int a = 2; a <=num; a++){
for (int i = 2; i <= a/2; i++){
if (a == 2 || a == 3 || a == 5){
isPrime = true;
}
else if (a % i == 0){
isPrime = false;
}
}
if (isPrime == true)
count++;
}
return count;
}
In your inner for loop, you are setting isPrime, but then you keep looping. Subsequent loops may set isPrime to false if a candidate divisor i doesn't divide cleanly. Only 2, 3, and 5, the 3 numbers in your first if condition, set it to true always, so you always get 3.
Instead, set isPrime to true at the beginning of the inner for loop, and break out of the inner for loop after each time you set isPrime. If the number is 2, 3, or 5, set to true and break so nothing can set it to false, so you can count it. If you found a factor, it's not prime, so set to false and break so nothing can set it to true and it's not counted.
Incidentally, your final if condition tests a boolean; it can be simplified to if (isPrime).
Your strategy is to test each number from 2 through num for primality by scanning for factors other than itself and 1. That's ok, albeit a bit simplisitic, but your implementation is seriously broken.
An approach involving scanning for factors implies that you start by guessing that the number being tested is prime, and then go looking for evidence that it isn't. You've missed the "guessing it's prime" part, which in your particular code would take the form of setting isPrime to true at the beginning of your outer loop.
Your code, on the other hand, never resets isPrime to true after testing the case of a == 5. That variable will be set to false when testing the case of a == 6, and will remain so for the duration. That is why you always get the result 3 for any input greater than 4.
If you properly reset isPrime in the outer loop then you can also remove the first part of the conditional in the inner loop, as it will be redundant. It is anyway never executed in the cases of a == 2 and a == 3 because the inner loop performs zero iterations in those cases.
Note also that it would be more efficient to break from the inner loop as soon as you determine that a is composite, and that you run more iterations of that loop than you need to do for primes (it would be sufficient to loop until i exceeds the square root of a; that is, until i * i > a).
Finally, note that this problem would be more efficiently implemented via the Seive of Eratosthenes (or one of the other prime number seives) as long as the numbers you want to test are not so large that the needed array would be prohibitively large.
I simplified your code by reducing number of operations which is needed to check if a is 2, 3, or 5.
public static int Prime(int num) {
int count = 0;
if (num >= 2) {
count++; // One optimization here
}
for (int a = 3; a <= num; a+=2) { // Another one here as we don't have any even number except 2 :D
boolean isPrime = true;
for (int i = 2; i <= a / 2; i++) {
if (a % i == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
count++;
}
}
return count;
}
#include <iostream>
using namespace std;
int numberOfPrimes(int num)
{
if(num==2)
return 1;
else if(num<2)
return 0;
int prime=1;
for(int i=3;i<=num;i++)
{
for(int j=2;j<=(i/2)+1;j++)
{
if(i%j==0)
break;
if(j==(i/2)+1)
prime++;
}
}
return prime;
}
package com.amit.primenumber;
public class PrimeNumber {
public static void main(String[] args) {
long number=23L;
String message=null;
PrimeNumber primeNumber = new PrimeNumber();
boolean result = primeNumber.primeNumber(number);
if(result){
message="a Prime Number";
}else{
message="Not a Prime Number";
}
System.out.println("The given "+number+" number is "+message);
}
public boolean primeNumber(long number){
for(long i=2;i<=number/2;i++){
if(number%i==0){
return false;
}
}
return true;
}
}
package basics;
public class CheckPrimeOrNot {
public void checkprimeNumber(int i){
int flag=0;
if(i>2){
for(int j = 2; j <= i/2; j++){
if(i%j == 0){
System.out.println("Given number is Not Prime");
flag=1;
break;
}
}
if(flag==0){
System.out.println("Given number is Prime");
}
} else{
System.out.println("Please enter a valid number");
}
}
public static void main(String[] args) {
CheckPrimeOrNot CheckNumber = new CheckPrimeOrNot();
CheckNumber.checkprimeNumber(11);
CheckNumber.checkprimeNumber(0);
CheckNumber.checkprimeNumber(250365);
CheckNumber.checkprimeNumber(1231);
}
}

NthPrime- what's wrong with this while/for loop or set of if-statements?

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.

Very simple prime number test - I think I'm not understanding the for loop

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);
}

Project Euler Number 3

First of all, this isn't homework... working on this outside of class to get some practice with java.
public class Problem3 {
public static void main(String[] args) {
int n = 13195;
// For every value 2 -> n
for (int i=2; i < n; i++) {
// If i is a multiple of n
if (n % i == 0) {
// For every value i -> n
for (int j=2; j < i; j++) {
if (n % j != 0) {
System.out.println(i);
break;
}
}
}
}
}
}
I keep modifying the code to try to make it do what I want.
As the problem says, you should be getting 5, 7, 13 and 29.
I get these values, plus 35, 65, 91, 145, 203, 377, 455, 1015, 1885, and 2639. I think I'm on the right track as I have all the right numbers... just have a few extras.
And in checking a few of the numbers in both being divisible by n and being prime numbers, the issue here is that the extra numbers aren't prime. Not sure what's going on though.
If anyone has any insight, please share.
This part
for (int j=2; j < i; j++) {
if (n % j != 0) {
System.out.println(i);
break;
}
doesn't check whether i is prime. Unless i is small, that will always print i at some point, because there are numbers smaller than i that don't divide n. So basically, that will print out all divisors of n (It wouldn't print the divisor 4 for n == 12, for example, but that's an exception).
Note also that the algorithm - using long instead of int to avoid overflow - even if fixed to check whether the divisor i is prime for deciding whether to print it, will take a long time to run for the actual target. You should investigate to find a better algorithm (hint: you might want to find the complete prime factorisation).
I solved this problem in Java and looking at my solution the obvious advice is start using BigInteger, look at the documentation for java.math.BigInteger
Also a lot of these problems are "Math" problems as much as they are "Computer Science" problems so research the math more, make sure you understand the math reasonably well, before coming up with your algorithm. Brute force can work some times, but often there are tricks to these problems.
Brut force can also work for checking whether factor is prime or not for this problem...
eg.
for(i=1;i<=n;i++)// n is a factor.
{
for(j=i;j>=1;j--)
{
if(i%j==0)
{
counter++;// set counter=0 befor.
}
if(counter==2) // for a prime factor the counter will always be exactly two.
{
System.out.println(i);
}
counter=0;
}
}
Don't know about Java but here is my C code if it is of any help.
# include <stdio.h>
# include <math.h>
// A function to print all prime factors of a given number n
void primeFactors(long long int n)
{
// Print the number of 2s that divide n
while (n%2 == 0)
{
printf("%d ", 2);
n = n/2;
}
int i;
// n must be odd at this point. So we can skip one element (Note i = i +2)
for ( i = 3; i <= sqrt(n); i = i+2)
{
// While i divides n, print i and divide n
while (n%i == 0)
{
printf("%d ", i);
n = n/i;
}
}
// This condition is to handle the case whien n is a prime number
// greater than 2
if (n > 2)
printf ("%ld ", n);
}
/* Driver program to test above function */
int main()
{
long long int n = 600851475143;
primeFactors(n);
return 0;
}
Its very good that you are working on such problems out of class.
Saw your code. You are writing a procedural code inside main function/thread.
Instead write functions and think step by step algorithmically first.
The simple algorithm to solve this problem can be like this:
1) Generate numbers consecutively starting from 2 which is the least prime, to 13195/2. (Any number always has its factor smaller than half of it's value)
2) Check if the generated number is prime.
3) If the number is prime then check if it is factor of 13195;
4) Return the last prime factor as it is going to be the largest prime factor of 13195;
One more advice is try writting seperate functions to avoid code complexity.
Code is like this...
public class LargestPrimeFactor {
public static long getLargestPrimeFactor(long num){
long largestprimefactor = 0;
for(long i = 2; i<=num/2;i++){
if(isPrime(i)){
if(num%i==0){
largestprimefactor = i;
System.out.println(largestprimefactor);
}
}
}
return largestprimefactor;
}
public static boolean isPrime(long num){
boolean prime=false;
int count=0;
for(long i=1;i<=num/2;i++){
if(num%i==0){
count++;
}
if(count==1){
prime = true;
}
else{
prime = false;
}
}
return prime;
}
public static void main(String[] args) {
System.out.println("Largest prime factor of 13195 is "+getLargestPrimeFactor(13195));
}
}

Categories

Resources