Java : Not sure if correct use of BigInteger - java

This program is meant to calculate the sum x amount of prime numbers under n, yet my code doesnt seem to work, it compiles and there are no errors.When I run it the console is just blank
public static void main(String[] args) {
Prime prime = new Prime();
BigInteger answer = BigInteger.valueOf(0);
for (int i = 2; i < 2000000; i++) {
if (prime.isPrime(i)) {
answer = answer.add(BigInteger.valueOf(i));
}
}
System.out.println(answer);
}
isPrime method
boolean isPrime(int n) {
for(int i = 2; i < n ; i++) {
if(n % i == 0) {
return false;
}
}
return true;
}

You are just not waiting long enough.
Try using i < 200 and you'll see the answer 4227 print out quite quickly.
You are checking 2,000,000 numbers for primality. Your isPrime method is O(n) so you are doing approximately 2,000,000 * 1,000,000 calculations. You work it out.

Why not use isProbablePrime() method from BigInteger class, if you using it anyway ?
for (int i = 2; i < 2000000; i++) {
if (new BigInteger(Integer.toString(i)).isProbablePrime(10)) {
answer = answer.add(BigInteger.valueOf(i));
}
}
This code runs only for around 4 seconds.
But if you want to do by your method, you should optimize it. It's necessary to check for divisors until sqrt(n)
for(int i = 3; i * i <= n ; i+= 2) {
if(n % i == 0) {
return false;
}
}
Or you can use the Sieve of Eratosthenes to solve your problem

Related

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

Prime numbers in a given range with less complexity

I have used below programs to find first n prime numbers (in below program it is from 2 to n). Can we write a program with single for loop? I also tried recursive approach but it is not working for me.
public static void main(String[] args) {
// Prime numbers in a range
int range = 15;
int num = 1;
int count = 0;
boolean prime = true;
while (count < range) {
num = num + 1;
prime = true;
for (int i = 2; i <= num / 2; i++) {
if (num % i == 0) {
prime = false;
break;
}
}
if (prime) {
count++;
System.out.println(num);
}
}
}
i dont think you can reduce it to one loop. But you can improve your code as Luca mentioned it.
public class PrimeFinder {
private final List<Integer> primes;
private final int primeCapacity;
public PrimeFinder(final int primeCapacity) {
if (primeCapacity < 3) {
throw new IllegalArgumentException("Tkat is way to easy.");
}
this.primeCapacity = primeCapacity;
primes = new ArrayList<>(primeCapacity);
primes.add(2);
}
public void find() {
final Index currentNumber = new Index();
while (primes.size() < primeCapacity) {
if (!primes.stream().parallel().anyMatch(prime -> (currentNumber.value % prime) == 0)) {
primes.add(currentNumber.incremet());
} else {
currentNumber.incremet();
}
}
}
public List<Integer> getPrimes() {
return primes;
}
private class Index {
public int value = 3;
public int incremet() {
return value++;
}
}
public static void main(String[] args) {
PrimeFinder primeFinder = new PrimeFinder(100000);
final long start = System.currentTimeMillis();
primeFinder.find();
final long finish = System.currentTimeMillis();
System.out.println("Score after " + (finish - start) + " milis.");
primeFinder.getPrimes().stream().forEach((prime) -> {
System.out.println(prime);
});
}
}
main rule here is simple, if given number isnt clearly divided by any prime number that you already have found, then it is prime number.
P.S. dont forget that primes.strem().... is loop also, so it is not a one loop code.
P.S.S. you can reduce this much further.
to understand the complexity of your algorithm you don't have to count the number of inner loops but the number of times you are iterating over your elements. To improve the performance of your algorithm you need to investigate if there are some iterations that could be unnecessary.
In your case when you do
for (int i = 2; i <= num / 2; i++) you are testing your num against values that are not necessary.. ex: if a number is divisible by 4 it will be by 2 too.
when you do for (int i = 2; i <= num / 2; i++) with num = 11
i will assume the values 2,3,4,5. 4 here is a not interesting number and represent an iteration that could be avoided.
anyway according to wikipedia the sieve of Eratosthenes is one of the most efficient ways to find all of the smaller primes.
public class PrimeSieve {
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
// initially assume all integers are prime
boolean[] isPrime = new boolean[N + 1];
for (int i = 2; i <= N; i++) {
isPrime[i] = true;
}
// mark non-primes <= N using Sieve of Eratosthenes
for (int i = 2; i*i <= N; i++) {
// if i is prime, then mark multiples of i as nonprime
// suffices to consider mutiples i, i+1, ..., N/i
if (isPrime[i]) {
for (int j = i; i*j <= N; j++) {
isPrime[i*j] = false;
}
}
}
// count primes
int primes = 0;
for (int i = 2; i <= N; i++) {
if (isPrime[i]) primes++;
}
System.out.println("The number of primes <= " + N + " is " + primes);
}
}
I don't know any way use a single loop for your question, but I do see two places where you can reduce the complexity:
Cache the prime numbers you found and use these prime numbers to decide if a number is prime or not. For example, to decide if 11 is a prime number, you just need to divide it by 2,3,5,7 instead of 2,3,4,5,6,...10
You don't need to check till num/2, you only need to check till the square root of num. For example, for 10, you only need to check 2,3 instead of 2,3,4,5. Because if number n is not prime, then n = a * b where either a or b is smaller than the square root x of n). If a is the smaller one, knowing that n can be divided by a is enough to decide that n is not prime.
So combining 1 & 2, you can improve the efficiency of your loops:
public static void main(String[] args) {
// Prime numbers in a range
int range = 15;
int num = 1;
int count = 0;
boolean prime = true;
ArrayList<Integer> primes = new ArrayList<>(range);
while (num < range) {
num = num + 1;
prime = true;
int numSquareRoot = (int) Math.floor(Math.pow(num, 0.5));
for (Integer smallPrimes : primes) {// only need to divide by the primes smaller than num
if (numSquareRoot > numSquareRoot) {// only need to check till the square root of num
break;
}
if (num % smallPrimes == 0) {
prime = false;
break;
}
}
if (prime) {
System.out.println(num);
primes.add(num);// cache the primes
}
}
}

Java code for project euler #7 gives wrong answer [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
This code is meant to find the 1001st prime but gives me the answer 47 which is clearly wrong.
public class problem7 {
public static void main(String[] args) {
int[] myarray = new int[1001];
int j = 0;
boolean prime = false;
for (int i = 2;; i++) {
for (int k = 2; k < i; k++) {
if (i == (k - 1) && i % k != 0) {
prime = true;
}
if (i % k == 0) {
prime = false;
prime = true;
}
if (prime) {
myarray[j] = i;
}
if (j == 1000) {
System.out.println(myarray[1000]);
return;
}
j++;
}
}
}
}
Any help would be greatly appreciated.
Your check for prime is wrong: you cannot declare a number prime and set prime = true based on a single test. The inner loop should set prime to false, but it shouldn't reset it to true: once it's false, it's false.
The algorithm should proceed as follows:
For each i, set prime=true
Loop over potential divisors k
If a divisor such that i % k == 0 is found, set prime = false, and break the loop
If prime is still true at the end of the nested loop, add i to the list of primes.
This should give you a correct result, at which point you should consider optimizing your solution using considerations below:
If you did not find a divisor among k below or at sqrt(i), then i is prime
You do not have to try all numbers k, only the ones from the list of primes that you have discovered so far.
I think j++ is increment only if prime number is inserted not at all case.By using this code you will be get your 1001 Prime number
public static void main(String[] args) {
int[] myarray = new int[1001];
int j = 0;
for (int i = 2;; i++) {
boolean prime = false;
for (int k = 2; k < i; k++) {
if (i % k == 0) {
prime = true;
}
}
if (!prime) {
myarray[j] = i;
j++;
}
if (j == 1001) {
break;
}
}
for (int primeNumber : myarray) {
System.out.println(primeNumber);
}
}
This is an implementation of dasblinkenlights algorithm!
public static void main(String args[]) {
int[] primes = new int[1001];
int i = 1;
int index = 0;
while (primes[1000] == 0) {
i++;
boolean skip = false;
for (int i1 : primes) {
if (i1 == 0)
break;
if (i % i1 == 0) { //checks if the number is a multiple of previous primes, if it is then it skips it
skip = true;
break;
}
}
if (!skip) {
if (isPrime(i)) {
primes[index] = i;
System.out.println(i);
index++;
}
}
}
}
static boolean isPrime(int n) {
for (int i = 2; i < n; i++) {
if (n % i == 0)
return false;
}
return true;
}
The primality test you done here is kind of ambiguous. Because the general approach is, we pick any number assuming its prime, so at the beginning, prime = true. Then if there exist any factor k of input such that k < input and kthen the number is not prime, so prime = false.
I modified your code and get a result: 104743 .
Update: Here is a bit faster way to find large prime. The inner loop will iterate up to square root of i, reason: Why do we check upto the square root of a prime number to determine if it is prime?
public static void main(String[] args) {
int[] myarray = new int[10001];
int j = 0;
boolean prime = true;
int i = 2;
while (true) {
prime = true;
for (int k = 2; k*k <= i; k ++) {
if (i % k == 0) {
prime = false;
}
}
if (prime) {
myarray[j] = i;
if (j == 10000) {
System.out.println(myarray[10000]);
return;
}
j++;
}
if(i > 4)
i += 2;
else
i++;
}
}

What's wrong with my Luhn algorithm code?

I'm trying to use this code to test if a sample code is a valid credit card number or not (using the Luhn algorithm) in Java. Where did I go wrong? It takes in an array of 16 one-digit numbers. Any help would be much appreciated. Thanks!
private static boolean isValidCC(int[] number) {
int sum = 0;
boolean alternateNum = true;
for (int i = number.length-1; i>=0; i--) {
int n = number[i];
if (alternateNum) {
n *= 2;
if (n > 9) {
n = (n % 10) + 1;
}
}
sum += n;
alternateNum = !alternateNum;
}
System.out.println(sum);
return (sum % 10 == 0);
}
Your code is correct except you started with the wrong alternate digit. Change to:
boolean alternateNum = false;
Judging from Wikipedia article --you've missed a checksum digit or erroneously taking it into account--.
Update: most probably, you've started with a wrong "alternate" flag.
There is a Java snippet, so why not use it?
public static boolean isValidCC(String number) {
final int[][] sumTable = {{0,1,2,3,4,5,6,7,8,9},{0,2,4,6,8,1,3,5,7,9}};
int sum = 0, flip = 0;
for (int i = number.length() - 1; i >= 0; i--) {
sum += sumTable[flip++ & 0x1][Character.digit(number.charAt(i), 10)];
}
return sum % 10 == 0;
}
Alternating digits are doubled counting from the end not the beginning.
instead of using your alternateNum bool try this.
if((number.length - i) % 2 == 0){
n *= 2;
...
}

Project Euler #10 Java solution not working

I'm trying to find the sum of the prime numbers < 2,000,000. This is my solution in Java but I can't seem get the correct answer. Please give some input on what could be wrong and general advice on the code is appreciated.
Printing 'sum' gives: 1308111344, which is incorrect.
Edit:
Thanks for all the help. Changed int to long and < to <= and it worked flawlessly, except for being an inefficient way of finding prime numbers :)
/*
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
*/
class Helper{
public void run(){
Integer sum = 0;
for(int i = 2; i < 2000000; i++){
if(isPrime(i))
sum += i;
}
System.out.println(sum);
}
private boolean isPrime(int nr){
if(nr == 2)
return true;
else if(nr == 1)
return false;
if(nr % 2 == 0)
return false;
for(int i = 3; i < Math.sqrt(nr); i += 2){
if(nr % i == 0)
return false;
}
return true;
}
}
class Problem{
public static void main(String[] args){
Helper p = new Helper();
p.run();
}
}
The result will be too large to fit into an integer, so you are getting an overflow. Try using a BigInteger or a long instead. In this case a long is enough.
You're treating as prime those numbers that are only divisible by their square root (like 25). Instead of i < Math.sqrt(nr) try i <= Math.sqrt(nr).
That's a really inefficient way to find primes, incidentally.
Your isPrime doesn't work for squares. isPrime(9) returns true.
As already stated errors were two:
you used an int that is not big enough to hold that sum.. you should have used a long
you used < instead that <=, and it was a wrong guard for the cycle
Apart from that what you are doing is really inefficient, without going too deep inside this class of algorithms (like Miller-Rabin test) I would suggest you to take a look to the Sieve of Eratosthenes.. a really old approach that teaches how to treat a complex problem in a simple manner to improve elegance and efficiency with a trade-off of memory.
It's really cleaver: it keeps track of a boolean value for every prime up to your 2 millions that asserts if that number is prime or not. Then starting from the first prime it excludes all the successive numbers that are obtained by multiplying the prime it is analyzing for another number. Of couse more it goes and less numbers it will have to check (since it already excluded them)
Code is fair simple (just wrote it on the fly, didn't check it):
boolean[] numbers = new boolean[2000000];
long sum = 0;
for (int i = 0; i < numbers.length; ++i)
numbers[i] = true;
for (int i = 2; i < numbers.length; ++i)
if (!numbers[i])
continue;
else {
int j = i + i;
while (j < 2000000) {
numbers[j] = false;
j += i;
}
}
for (int i = 2; i < 2000000; ++i)
sum += numbers[i] ? i : 0;
System.out.println(sum);
Of course this approach is still unsuitable for high numbers (because it has to find all the previous primes anyway and because of memory) but it's a good example for starters to think about problems..
by using Sieve of Eratosthenes effectively, i solved the problem, here is my code
public class SumOfPrime {
static void findSum()
{
long i=3;
long sum=0;
int count=0;
boolean[] array = new boolean[2000000];
for(long j=0;j<array.length;j++)
{
if((j&1)==0)
array[(int)j]=false;
else
array[(int)j]=true;
}
array[1]=false;
array[2]=true;
for(;i<2000000;i+=2)
{
if(array[(int)i] & isPrime(i))
{
array[(int)i]=true;
//Sieve of Eratosthenes
for(long j=i+i;j<array.length;j+=i)
array[(int)j]=false;
}
}
for(int j=0;j<array.length;j++)
{
if(array[j])
{
//System.out.println(j);
count++;
sum+=j;
}
}
System.out.println("Sum="+sum +" Count="+count);
}
public static boolean isPrime(long num)
{
boolean flag=false;
long i=3;
long limit=(long)Math.sqrt(num);
for(;i<limit && !(flag);i+=2)
{
if(num%i==0)
{
flag=false;
break;
}
}
if(i>=limit)
flag=true;
return flag;
}
public static void main(String args[])
{
long start=System.currentTimeMillis();
findSum();
long end=System.currentTimeMillis();
System.out.println("Time for execution="+(end-start)+"ms");
}
}
and the output is
Sum=142913828922 Count=148933
Time for execution=2360ms
if you have doubt, please do tell
Here is my solution
public class ProjectEuler {
public static boolean isPrime(int i) {
if (i < 2) {
return false;
} else if (i % 2 == 0 && i != 2) {
return false;
} else {
for (int j = 3; j <= Math.sqrt(i); j = j + 2) {
if (i % j == 0) {
return false;
}
}
return true;
}
}
public static long sumOfAllPrime(int number){
long sum = 2;
for (int i = 3; i <= number; i += 2) {
if (isPrime(i)) {
sum += i;
}
}
return sum;
}
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(sumOfAllPrime(2000000));
}
}

Categories