Generating primes using nested loops (java). Problem with loops - java

I already generated primes using the Sieve of Eratosthenes algorithm (I asked about it here Sieve of Eratosthenes, generating primes. Problem with loops)
But now I have to do it using only an array and nested loops.
I tried to apply this approch https://examples.javacodegeeks.com/java-basics/for-loop/generate-prime-numbers-with-for-loop/, but I can't get why it doesn't work correctly for me
I just want to check if a number is prime and add it to my array
Could u help me pls?
public class Part6 {
public static int[] primeSequence(int n) {
int[] primes = new int[n];
for (int i = 2; i < n; i++) {
boolean isPrimeNumber = true;
for (int j = i + 1; j < i; j++) {
if(j % i == 0)
isPrimeNumber = false;
break;
}
if (isPrimeNumber)
primes[i] = i;
}
return primes;
}
public static void main(String[] args) {
for (int number : primeSequence(Integer.parseInt(args[0]))) {
System.out.print(number);
}
}
}

You are missing braces in your inner loop, your inner loop doesn't get executed (int j = i + 1; j < i!), the order of operands in the modulo operation is wrong and the inner loop should probably start at 2.
for (int j = 2; j < i; j++) {
if(i % j) == 0){
isPrimeNumber = false;
break;
}
}

If we start the second loop from j=i+1 then we will miss many numbers which might be a divisor of the number i. So, to check if i is a prime or not we should start with j=2 for every i-th iteration.
Also, inside every nested loop we are checking if i is Prime or not so, we should whether i % j == 0 or not.
Here is a modified version:
public static int[] primeSequence(int n)
{
int k = 0;
int[] primes = new int[n];
for (int i = 1; i < n; i++)
{
boolean isPrimeNumber = true;
for (int j = 2; j < i; j++)
{
if (i % j == 0)
{
isPrimeNumber = false;
break;
}
}
if (isPrimeNumber)
primes[k++] = i;
}
return primes;
}

Related

What is the 10001st prime number? Why does my Java solution give the error ArrayIndexOutOfBoundsException?

So this is my Java code for Project Euler #7(description of problem commented out in code):
// By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
// What is the 10001st prime number?
boolean isPrime = true;
long [] primes = new long[10001];
int j = 0;
while (j < 10001){
for (long i = 2; i < 1000000000000000L; i++) {
for (long k = i; k < i / 2; k++) {
if (i % k == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
primes[j] = i;
j++;
}
}
}
System.out.println(primes[10000]);
When I run this code, this is what I get as a result :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10001
*at vasila.mir.Main.main(Main.java from InputFileObject:22)*
When I press on the ArrayIndexOutOfBoundsException error it gives me this "Find why 'j' could be 10001". When I press on that, this is what I get :
primes[j] = i; in Main.main(String[]) (filter: 10001)
I don't understand what that means, and it doesn't really help me.
What could be the problem with my code?
If your for (long i = 2; i < 1000000000000000L; i++) finds more that 10001 primes, your outer loops condition is never checked in time to finish the program.
You should combine the loops
Change
while (j < 10001){
for (long i = 2; i < 1000000000000000L; i++) {
to
for (long i = 2; i < 1000000000000000L && j < 10001; i++) {
You should also reset isPrime to true at the start of the outer for loop.
And in the inner loop, k should start at 2, not i.
The following works:
long [] primes = new long[10001];
int j = 0;
for (long i = 2; i < 1000000000000000L && j < 10001; i++) {
boolean isPrime = true;
for (long k = 2; k <= i / 2; k++) {
if (i % k == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
primes[j] = i;
j++;
}
}
System.out.println(primes[10000]);
Output:
104743

Numerical triangle using java

How do I stop the loop if the number reaches the n? i tried the break; but the loop still doesn't stop.
Scanner in = new Scanner(System.in);
int i, j;
int n = in.nextInt();
int number = 1;
for(i = 1; i <= n; ++i) {
for(j = 1; j <= i; ++j) {
System.out.print(number);
++number;
if(number >= n){
break;
}
}
System.out.println();
}
input: 9
expected output:
1
23
456
789
or
input: 12
expected output:
1
23
456
78910
1112
Break and Labeled break should be avoided in code. So you can use loops as below:
public static void main(final String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Please enter input number:");
int n = in.nextInt();
System.out.println("You have entered : " + n);
for (int i = 1, k = 1; k <= n; i++) {
for (int j = 0; j < i && k <= n; j++, k++) {
System.out.print(k);
}
System.out.println();
}
}
Printing k variable which is initialized in outer and updated in inner loop.
Putting condition to break inner and outer loop to check k with input variable
EDITED : To understand it better:
i variable is used to maintain the number of rows we need to print.
j variable is used to maintain the number to elements to print in each row.
In most of placed the value which is being print is in context with either row number or element number in row, but here print value is not in sync with it, so we are maintaining it in 2rd variable k.
Use the labeled break statement and you can break from the nested loop:
loop:
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= i; ++j)
{
System.out.print(number);
++number;
if (number > n) //not (number >= n)
{
break loop;
}
}
System.out.println();
}
There are many ways of doing this. The most straightforward one is to use a label to break out of several loops at once:
outer: for(i = 1; i <= n; ++i) { // a label is a word followed by :
inner: for(j = 1; j <= i; ++j) { // you can declare labels without using them
System.out.print(number);
++number;
if(number >= n){
break outer; // break inner would be equivalent to what you had
}
}
System.out.println();
}
However, these break statements with labels look suspiciously similar to gotos, and gotos are frowned upon. A more teacher-friendly version would be to use a boolean flag, and check the flag in each loop:
boolean finished = false;
for(i = 1; i <= n && ! finished; ++i) {
for(j = 1; j <= i && ! finished; ++j) {
System.out.print(number);
++number;
if (number >= n) {
finished = true; // no need to break - loops condition will now be false
}
}
System.out.println();
}
Note that this introduces an extra newline, which you generally want to make sure that whatever you print next appears on a different line.
Another option is to simply complicate your initial condition, without any flags:
for(i = 1; i <= n && number < n; ++i) {
for(j = 1; j <= i; ++j) {
System.out.print(number);
++number;
}
System.out.println();
}
I would recommend, for readability purposes, version 2. Additionally, I would write it as follows:
boolean finished = false;
for(int i = 0; i < n && ! finished; ++i) {
for(j = 0; j < i && ! finished; ++j) {
System.out.print(number++);
if (number >= n) {
finished = true;
}
}
System.out.println();
}
The key differences are using 0 to n-1 counting to repeat something n times (most programmers are very accustomed to that, instead of counting from 1 to n), and defining loop variables within the for, so that trying to use them outside of their loops is an error. This helps to avoid accidental reuse of variables.
import java.util.Scanner;
public class Tester{
public static void main(String []args){
Scanner in = new Scanner(System.in);
int i, j;
int n = in.nextInt();
int number = 1;
loop:
for ( i = 1; i <= n; ++i){
for ( j = 1; j <= i; ++j){
System.out.print(number);
++number;
if (number > n)
{
break loop;
}
}
System.out.println();
}
}
}
by using a for loop with a nested one you can achieve it like this:
you have a row which is incremented by 1 on each row (line)
you have a column variable which is increasing by one on each line or row
you have a number with start to print from 1 till the inputed number for example it was entered 12.
in inner loop you need to check the column be less or equal to row and the incremented number be less the entered number.
Scanner in = new Scanner(System.in);
System.out.print("Enter a Number: ");
int n = in.nextInt();
int number = 1;
for (int row = 1; row <= n && number <= n; row++) {
for (int column = 1; column <= row && number <= n; column++) {
System.out.print((number++) + " ");
}
System.out.println();
}

Need help optimizing Java program for Goldbach Conjecture

I need to print all prime numbers from 1 to 1,000,000 and print all even numbers from 4 to 10,000 and two prime numbers that sum to it.
I have a sieve method that changes all non-prime numbers in an array to a 0 (the problem specifically asks for this to be done), and I need to use a goldbach method that passes this array and displays all even numbers from 4 to 10,000 and two primes that sum up to that number.
The point of the goldbach portion of the problem is to print the numbers efficiently, and I am pretty sure my solution uses a polynomial time search when the correct solution is to be done with a linear time search. Any clue on how I might optimize this?
import java.lang.Math;
public class sieveAndGoldbach {
public static void sieve(int[] a) {
int n = a.length;
a[0] = 0;
for (int i = 1; i <= Math.sqrt(n); i++) {
if (a[i] != 0) {
for (int j = a[i]*a[i]; j <= n; j+=a[i]) {
a[j-1] = 0;
}
}
}
}
public static void goldbach(int[] a) {
int max = 10000;
for (int i = 4; i <= max; i += 2) {
int count = 0;
for (int j = 0; j < i/2; j++) {
if (a[j] != 0) {
int difference = i-a[j];
for (int k = 0; k < max; k++) {
if (a[k] == difference && count == 0) {
System.out.println(i + " = " + a[j] + " + " + (difference));
count++;
}
}
}
}
}
}
public static void main(String[] args) {
//initialize and fill array from 1 to n
int n = 1000000; //initially one million GOLDBACH METHOD WILL NOT WORK FOR n < 10,000
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = i + 1;
}
//Call sieve method on array a, then print all primes, not the zeros
sieve(a);
for (int i = 0; i < n; i++) {
if (a[i] != 0) {
System.out.print(a[i]);
System.out.print(" ");
}
}
System.out.print("\n");
//Call goldbach method on array a
goldbach(a);
}
}
You currently seem to be iterating through the array of primes for each prime looking for one that sums to your target. That's not necessary; you just need to check whether the difference is a prime:
int[] primes;
int target;
for (int i = 2; i < target / 2; i++) {
if (primes[i] != 0 && primes[target - i] != 0)
...
}
Beyond that I can't see a lot of obvious optimisation but there may well be some numerical analysis that allows you to target likely primes first.

All the perfect numbers between 1 and 500 program algorithm says it works but it doesn't

I am writing a program to tell me all the perfect numbers between 1 and 500 and I made this program, but it doesn't work although the algorithm makes sense.
import java.util.Scanner;
class allPerfect {
public static void main(String args[]) {
int sum = 0;
System.out.println("All perfect numbers between 1 and 500 are:");
for (int j = 0; j != 501; j++) {
for (int i = 1; i < j; i++) {
if (j % i == 0) {
sum = sum + i;
if (sum == j) {
System.out.println(j);
sum = 0;
} else {
sum = 0;
}
}
}
}
}
}
What's wrong here?
Please find the comment in-line.
class allPerfect {
public static void main(String args[]){
int sum;
System.out.println("All perfect numbers between 1 and 500 are:");
for(int j = 1; j!=501; j++){
sum = 0; //**You should reset the sum at the start of the inner loop.**
for(int i = 1; i < j; i++ ){
if(j % i == 0) {
sum = sum + i;
}
}
if(sum == j) { //------ statement-1
System.out.println(j);
}
}
}
}
statement-1 you check the sum of all the divisor is equal to the number, after summing up for all the numbers less than j.
You can ignore all the odd number (j) in outer loop, because odd perfect number does not exist. To be precise: it is not known that odd perfect number exists.
You are resetting sum before you finish finding all of a numbers divisors.
for(int i = 1; i < j; i++ ){
if(j % i == 0){
sum = sum + i;
if(sum == j){
System.out.println(j);
sum = 0;
}else{
sum = 0;
}
}
}
You should do the if(sum == j) only after you exit the inner for loop.

Prime numbers calculator takes too much time (JAVA)

When I run this code to find sum of prime numbers below 20 it works fine, but when try to find sum below 2500000 it takes too much time. It's been at least 20 minutes and it's still running. It seems like it's not working. How do I fix it?
class PrimeSummation {
public static void main(String[] args) {
int sum = 0;
for(int i = 1; i < 2500000; i++) {
int count = 0;
for(int j = 1; j < i + 1; j++) {
if((i%j) == 0) {
count++;
}
}
if(count == 2) {
sum += i;
}
}
System.out.println(sum);
}
}
sum cannot be an int because the answer is 219697708195 whereas Integer.MAX_VALUE is only 2147483647. You must use a long or a BigInteger instead.
Your algorithm is very slow, because for every one of the 2500000 numbers you are starting from scratch to decide whether it is prime or not, and your approach for testing whether a number is prime (try every possible factor) is not very efficient.
The following code produces the answer in about a tenth of a second on my machine.
int num = 2500000;
long sum = 0;
boolean[] arr = new boolean[num];
for (int p = 2; p < num; p++) {
if (!arr[p]) {
sum += p;
for (int k = p * 2; k < num; k += p)
arr[k] = true;
}
}
System.out.println(sum);
Keeping track of previously found primes seems to help:
BigInteger sum = BigInteger.ZERO;
List<Integer> primes = new ArrayList<>();
for(int i = 2; i < 2500000; i++) {
boolean isPrime = true;
for(int j = 0; j < primes.size() && primes.get(j)<= Math.sqrt(i); j++) {
int p = primes.get(j);
if((i%p) == 0) {
isPrime=false;
break;
}
}
if(isPrime) {
sum = sum.add(BigInteger.valueOf(i));
primes.add(i);
}
}
System.out.println(sum);
Came up with answer:
219697708195
If you want better performance for generating a large number prime number, you should use Sieve formula.
You can Learn Sieve_of_Eratosthenes formula for prime number generation.
According to Sieve_of_Eratosthenes:
import java.util.*;
public class Sieve
{
private BitSet sieve;
private Sieve() {}
private Sieve(int size) {
sieve = new BitSet((size+1)/2);
}
private boolean is_composite(int k)
{
assert k >= 3 && (k % 2) == 1;
return sieve.get((k-3)/2);
}
private void set_composite(int k)
{
assert k >= 3 && (k % 2) == 1;
sieve.set((k-3)/2);
}
public static List<Integer> sieve_of_eratosthenes(int max)
{
Sieve sieve = new Sieve(max + 1); // +1 to include max itself
for (int i = 3; i*i <= max; i += 2) {
if (sieve.is_composite(i))
continue;
// We increment by 2*i to skip even multiples of i
for (int multiple_i = i*i; multiple_i <= max; multiple_i += 2*i)
sieve.set_composite(multiple_i);
}
List<Integer> primes = new ArrayList<Integer>();
primes.add(2);
for (int i = 3; i <= max; i += 2)
if (!sieve.is_composite(i))
primes.add(i);
return primes;
}
}
Performance:

Categories