I am trying to solve Spoj prime generator using Sieve Of Eratosthenes But am getting NZEC error. Can anybody help me . Some users have said using sieve already would help me .
import java.util.*;
public class Main
{
public static void main (String args[])
{
Scanner sc =new Scanner(System.in);
int n =sc.nextInt();
int g,h;
int isPrime[]=new int[1000000000];
for (int j=3;j<1000000000;j++)
{
isPrime[0]=0;
isPrime[1]=0;
isPrime[2]=1;
if(j%2==0)
isPrime[j]=0;
else
isPrime[j]=1;
}
for(int k=3;k<=Math.sqrt(1000000000);k=k+2)
{
if(isPrime[k]==1)
for (int l=k*k;l<1000000000;l=l+k)
{
isPrime[l]=0;
}
}
for (int i=0;i<n;i++)
{
g =sc.nextInt();
h =sc.nextInt();
for (int m=g; m<=h;m++)
{
if(isPrime[m]==1)
System.out.println(m);
}
System.out.println();
}
System.exit(0);
}
}`
Simple sieve may not run in the given time limit. At least it didn't for me. The better approach is segmented sieve. Here are few links that may help you:
stackoverflow
primesieve
I used the second link to understand and solve the question. But the first link also has a good explanation.
Go through both of them and you should be able to solve the problem.
Happy Coding!
P.S: You seem to be using Scanner for reading input. It will be very slow. Use BufferedReader to speed up the reading of inputs. In websites like SPOJ, it is very crucial.
Only reason is just JVM should have enough space to store new boolean[total + 1] about 4Gb:
public static void main(String... args) {
boolean[] primes = primes(1_000_000_000);
try (Scanner scan = new Scanner(System.in)) {
int n = scan.nextInt();
for (int i = 0; i < n; i++) {
int from = scan.nextInt();
int to = scan.nextInt();
for (int j = from; j <= to; j++)
if (primes[j])
System.out.println(j);
System.out.println();
}
}
}
private static boolean[] primes(int total) {
// initially assume all integers are primes
boolean[] primes = new boolean[total + 1];
Arrays.fill(primes, true);
primes[0] = false;
primes[1] = false;
// mark non-primes <= total using Sieve of Eratosthenes
for (int i = 2; i * i <= total; i++) {
// if i is primes, then mark multiples of i as nonprime
// suffices to consider mutiples i, i+1, ..., total/i
if (!primes[i])
continue;
for (int j = i; i * j <= total; j++)
primes[i * j] = false;
}
return primes;
}
Related
I need some help. My professor give us an assignment that we need to "extract" these codes into ONE METHOD ONLY. Is there a way to do it? It's a heap code sorting algorithm. I'm currently do have a little knowledge about programming so bear with me guys. Can you help me?
import java.util.Arrays;
import java.util.Scanner;
class HeapSort {
private static Scanner sc;
public static void main(String args[]) {
sc = new Scanner(System.in);
System.out.println("Enter no of terms");
int n = sc.nextInt();
System.out.println("Enter the terms");
int arr[] = new int[n];
for (int i = 0; i < n; i++)
arr[i] = sc.nextInt();
System.out.println("The unsorted array is:");
System.out.println(Arrays.toString(arr));
heap(arr);
System.out.println("The sorted array is:");
System.out.println(Arrays.toString(arr));
}
static void heapify(int a[], int n, int i) {
int max, child;
child = 2 * i + 1;
max = i;
if (child < n)
if (a[child] > a[max])
max = child;
if (child + 1 < n)
if (a[child + 1] > a[max])
max = child + 1;
if (max != i) {
int temp = a[i];
a[i] = a[max];
a[max] = temp;
heapify(a, n, max);
}
}
static void buildheap(int a[]) {
for (int i = a.length / 2 - 1; i >= 0; i--)
heapify(a, a.length, i);
}
static void heap(int a[]) {
buildheap(a);
for (int i = a.length - 1; i >= 1; i--) {
int temp = a[0];
a[0] = a[i];
a[i] = temp;
heapify(a, i, 0);
}
}
}
You get there by simply replacing each method invocation with the actual body of the method. Of course, that will quickly lead to all kinds of confusion, given the poor naming of method parameters.
But the real challenge here (and probably your actual homework) is that you have to rework that heapify() method to not use recursion. In other words: you have to do the heap sort without using recursion. You can find some guidance here for example.
And of course: this code is already hard to read. Forcing all code into a single method will make it unreadable and not human comprehensive. It is like the exact opposite of good practices!
One thing you can do is replace all the code in each method to where the method is being called.
For example, instead of calling heap(arr) you can move all the code up to the place where heap(arr) is being called and continue to do so with the rest of the code.
Edit: I need to do the following with the array: sort, find minimum, find maximum, find the average.
1) How do I properly access the methods in the other class 2) What variables do I need to initialize in order to make my methods work (since I got the examples from Google)
I've tried to find examples of how to work with the numbers in an array, but I find it difficult to figure out considering the code is working with different variable names and is largely unorganized and not commented.
This is what I have so far in my methods class:
//Grades Array
int[] score = {70,90,80,85,65,55,100,70,40,77,66,55,44};
int number;
//Get
public int getNumber(){
return number;
}
//Average Grade
public static double average(int[] score, int number)
{
double average = 0;
if (score.length > 0)
{
average = number / score.length;
}
return average;
}
Here is my Main class:
public class Main {
public static void main(String[] args) {
//Average Method
OtherMethods average = new OtherMethods();
int[] number = null;
OtherMethods.average(number, 0);
System.out.println(number);
}
}
So as you can see I'm all over the place. It's largely a patchwork of examples I've tried to apply.
This is the Sort code I'm using. Adhering my variables to the ones used here would be advantageous, of course, but I'm just not sure where to begin.
//Ascending Sort Method
public static void sort(int[] score, int number)
{
for(i=0; i < num-1; i++) //For each sublist
{
min = list[i];
position = i;
for (j=i+1; j < num; j++) //Find minimum
{
if (list[j] < min)
{
min = list[j];
position = j;
}
}
temp = list[position]; //Swap
list[position] = list[i];
list[i] = temp;
}
}
Any help would be greatly appreciated.
If you're using Java 8+, Check out the functional streams and in particular IntStream.
For Example, to min/max/average:
int min = IntStream.of(score)
.min(); // or .max() or .average()
and to sort:
score = IntStream.of(score)
.sorted()
.toArray();
If your trying to sort the numbers you can do something as simple as the bubble sort, which is fairly strait forward compare n to n+1 and switch if need be:
void bubbleSort(int ar[])
{
for (int i = (ar.length - 1); i >= 0; i--)
{
for (int j = 1; j ≤ i; j++)
{
if (ar[j-1] > ar[j])
{
int temp = ar[j-1];
ar[j-1] = ar[j];
ar[j] = temp;
} } } }
or like you did above the selection sort:
void selectionSort(int[] ar){
for (int i = 0; i ‹ ar.length-1; i++)
{
int min = i;
for (int j = i+1; j ‹ ar.length; j++)
if (ar[j] ‹ ar[min]) min = j;
int temp = ar[i];
ar[i] = ar[min];
ar[min] = temp;
} }
Another thing the way you currently have this set up your getNumber() function has no real use seeing that your number variable is global to begin with.
If you want more help you will have to come up with an actual question.
This program is supposed to print all the prime numbers up to an int that you enter, for example:
Enter a Number:
20
2
3
5
7
11
13
17
19
I just cannot get my program to work, I really don't know what to do, so if someone could review it and try to fix it, that would be greatly appreciated, thanks.
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
PrimeGenerator matt = new PrimeGenerator();
System.out.println(matt.nextPrime(number));
}
private int number;
public PrimeGenerator(int n) {
number = n;
}
public int nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i;
}
}
}
}
You're already there actually. You've just got a mistake in the program-flow.
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i; //<-- this return will terminate nextPrim
}
}
Things to fix/improve:
nextPrim would need to return a value within every possible program-branch. This means: consider the case where nextPrim doesn't find any number in the given range and steps out of the loop. Now the program would be stuck without any return-value.
Instead of returning the first prim-number found, you could print that found prim-number and keep the generator running. Nice, easy and solves the hassle with returning anything, since you now can simply declare nextPrim as void. I'd recommend renaming it to printPrims or something like that to make this change clear.
Passing number: You can save a bit of effort by only passing number once to the prim-generator. The simplest solution would be to pass it to nextPrim/printPrims. Now you can remove the instance-variable number and the constructor, which solves the issue with th e signature of the constructor.
1 is not a prim-number to be pedantic. So let's be pedantic and start the outer loop in printPrims with 2, so that 2 will be the first number that is checked for being a prim.
So let's put this into code:
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
PrimeGenerator matt = new PrimeGenerator();
matt.printPrims(number);
}
public void printPrime(int number) {
for (int i = 2; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
A few general hints:
Work through compiler errors. They tell you precisely where and what errors occur within your code.
Think about the flow of your program before even implementing it.
Break the task down into smaller tasks and implement these one after another. As an example: for this problem first print out all numbers in the range 2, number. Afterwards go a step further and add functionality to filter out prim-numbers. Now you've got two components that you can easily test independent of each other.
You were nearly there but your nextPrimes function was terminating prematurely when you returned i, try something like this:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner k = new Scanner(System.in);
System.out.print("Enter an integer:");
int number = k.nextInt();
printPrimesUptoN(number);
}
public static void printPrimesUptoN(int n){
for(int i=2;i<n;i++){
boolean isPrime = true;
for(int j=2;j<i;j++){
if(i % j == 0){
isPrime = false;
break;
}
}
if(isPrime)
System.out.println(i);
}
}
}
Try it here!
There's a few issues with your code, maybe we can fix it together. First things first, you're missing a return statement in nextPrime and there's no empty default constructor PrimeGenerator() because you created a single-arg constructor. Try this:
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
// you probably want to pass your maximum value to the constructor
PrimeGenerator matt = new PrimeGenerator(number);
// without a loop of some sort this will only print a single prime number, e.g.
// Enter a Number:
// 20
// 2
System.out.println(matt.nextPrime(number));
}
private int number;
public PrimeGenerator(int n) {
this.number = n;
}
// you're using the argument as upper boundary for your prime detection while not increasing your lower boundary
// also you're checking if i is a prime here which you always start at 1. this should always return the same value because once you find a prime number you return
// you should consider using an algorithm like Sieve of Eratosthenes (or advanced verions thereof) to determine if a given number is prime
public int nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i;
}
}
// you need to return something at the end of this method or throw an exception
throw new IllegalStateException("no more prime numbers available!");
}
}
This is not a solution which will yield the results you're expecting but it will compile at least. From that point you can move forward and fix the algorithmic issues.
Your original error was in.
PrimeGenerator matt = new PrimeGenerator();
Error:
PrimeGenerator.java:7: error: constructor PrimeGenerator in class PrimeGenerator cannot be applied to given types;
PrimeGenerator matt = new PrimeGenerator();
^
required: int
found: no arguments
reason: actual and formal argument lists differ in length
1 error
Notice that you had a method with the same name as you class, but I don't think you were using it as a constructor and if you were it took an int which you didn't give it. Your method on line 13 was:
public PrimeGenerator(int n) {
number = n;
}
Try doing
new PrimeGenerator().nextPrime(number);
Instead
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
new PrimeGenerator().nextPrime(number);
}
public void nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
}
Optionally, to use your original constructor, you could separate this out.
import java.util.Scanner;
public class PrimeGenerator {
private int number;
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
// Initialize with a number.
PrimeGenerator pg = new PrimeGenerator(number);
pg.printPrimes();
}
// This is the constructer you were misusing.
public PrimeGenerator(int n) {
number = n;
}
public void printPrimes() {
// Actually use your private number variable.
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
}
There are several issues:
Are you using an IDE? If so, which is it, else Why not?. If you consider yourself a beginner, be advised to used one, like Eclipse IDE or NetBeans IDE.
Regarding to your algorithm, at first glance, there is a compilation and a logic problems.
Compilation problem is when the execution of your class not work. In this case the method nextPrime(int number) MUST return an int. Although you put return clause, the method is not returning any value when prime is false. You could easily spot this problem with an IDE.
Another compilation problem, the sentinel or variable i is INSIDE the for loop, and you are printing it's value OUTSIDE of it. Once again, the IDE would help you with this problem.
Logic problem is, you are returning a value if and only if the flag prime is true, so, when calling the method (supposing is working) you only obtain ONE value when you call System.out.println(matt.nextPrime(number));
The correct implementation would have these considerations:
The method doesn't return, i.e public void nextPrime(number) { ..., which means you don't need print in the main method, just call it.
The method actually prints the numbers.
In this way, you can check if i % j is different of zero, then you don't need to process more dividers, breaking the for loop.
Print it.
That's it.
public static void main(String [] args) {
.
.
.
PrimeGenerator matt = new PrimeGenerator();
matt.nextPrime(number);
}
public void printPrime(int number) {
boolean prime = true;
for (int i = 2; i <= number; i++) {
prime = true;
for (int j = 2; j < i; j++) {
if (i % j != 0) {
prime = false;
break;
}
}
if (prime) {
System.out.println(i);
}
}
}
Today while solving this question on HackerRank I used Array stream .sum() function to sum all the entries and proceeded with my algorithm. But for sum reason I found that my algorithm fails for some cases. I used diff to find out it passes 99% cases and for 1% the output is nearly equal but is less than the original answer. That's why I replaced the stream .sum() with a for loop and unexpectedly it passed all the test cases. I tried but couldn't ascertain this uncertain behaviour.
My implementation using stream.sum() :
public class MandragoraForest {
public static void main(String[] args) {
InputReader in = new InputReader(System.in);
for (int i = in.nextInt(); i > 0; i--) {
int number = in.nextInt();
int[] h = new int[number];
for (int j = 0; j < number; j++) h[j] = in.nextInt();
System.out.println(new MandragoraForestSolver().solve(h));
}
}
}
class MandragoraForestSolver {
public long solve(int[] h) {
if (h.length==1) return h[0];
Arrays.parallelSort(h);
long sum = Arrays.stream(h)
.sum();
long ans = -1;
for (long i=0, strength = 2; i<h.length; i++, strength++) {
sum -= h[(int)i];
ans = Math.max(ans, strength * sum);
}
return ans;
}
}
Implementation without Java stream :
public class MandragoraForest {
public static void main(String[] args) {
InputReader in = new InputReader(System.in);
for (int i = in.nextInt(); i > 0; i--) {
int number = in.nextInt();
int[] h = new int[number];
long sum = 0;
for (int j = 0; j < number; j++) {
h[j] = in.nextInt();
sum += h[j];
}
System.out.println(new MandragoraForestSolver().solve(h, sum));
}
}
}
class MandragoraForestSolver {
public long solve(int[] h, long sum) {
if (h.length==1) return h[0];
Arrays.parallelSort(h);
long ans = -1;
for (long i=0, strength = 2; i<h.length; i++, strength++) {
sum -= h[(int)i];
ans = Math.max(ans, strength * sum);
}
return ans;
}
}
Is there something that I'am missing out ? What could be the reason for this behaviour?
There is one significant difference between using a stream and a loop - the possibility of arithmetic overflow.
Arrays.stream(int[]) returns an IntStream, whose sum() method returns an int result. If the sum exceeds Integer.MAX_VALUE, a silent integer overflow will occur.
However your loop sums by adding int values to a long total, which would not suffer from arithmetic overflow.
The sum of integers in one of the tests must exceed Integer.MAX_VALUE, testing that a long is used to (correctly) calculate the total.
If you want to use a stream to sum, you need to convert the IntStream to a LongStream, which you can do like this:
long sum = Arrays.stream(big).asLongStream().sum();
I've been trying to solve this rather easy problem on SPOJ: http://www.spoj.com/problems/HS08PAUL/.
It requires the number of prime numbers (less than n) which can be expressed in the form x^2+y^4 (where x and y are integers) to be found out.
I've whipped up a brute force solution which takes up quite a while for (n ~= 1000000), resulting in a TLE (time limit exceeded) error being thrown by the engine. Here's the source code:
import java.io.*;
import java.util.*;
class HS08PAUL {
public static int[] sieve(int n){
boolean[] prime = new boolean[n+1];
int[] primeNumbers = new int[n];
int index = 0;
Arrays.fill(primeNumbers, 0);
Arrays.fill(prime,true);
prime[0] = false;
prime[1] = false;
int m = (int)Math.sqrt(n);
for(int i = 2; i <= m; i++){
if(prime[i])
for(int k = i*i; k<=n; k+=i)
prime[k] = false;
}
for(int j = 2; j <= n; j++) {
if(prime[j]) {
primeNumbers[index] = j;
index++;
}
}
return primeNumbers;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
try{
double numberOfTestCases = in.nextDouble();
while(numberOfTestCases -- > 0) {
int index = 0, y = 0, count = 0;
int num = in.nextInt();
int[] primes = sieve(num);
while(index < num/3 ) {
for(y = 1; y < 57 ; y ++) {
if(Math.ceil(Math.sqrt(primes[index] - Math.pow(y,4))) == Math.floor(Math.sqrt(primes[index] - Math.pow(y,4)))) {
count++;
break;
}
}
index++;
}
System.out.println(count);
}
}
catch(Exception e) {
}
}
}
Is there a way in which I can make this approach work?
P.S.:Please ignore the unruly exception handling.
How many numbers of the form x^2+y^4 are there below 1000000? How many prime numbers are there below 1000000? What do these two numbers tell you about how you should approach the solution?
#isnot2bad's comment is also relevant.