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.
Related
just to preface, I am very new to coding in Java, or coding in general to be exact.
Here is what I am trying to accomplish. It is a project, where we take a input file of numbers, one integer being a competitor number, the next being their weight for a fish they caught, (Looking like this 3 26.7 (new line per two numbers) 2 2.6.. so on and so on), put them in a array, then sort them in one way or another. Now, I will post the whole code, but it is only the last method, "sort", that I am having difficulties right now.
The method is a bubble sorting method. The way I am approaching it is so that it will take the first array, compare it with the second array to see if it is less than, then swap the two competitor numbers if the logic is correct so that I can print the competitor numbers in the main method, and call the appropriate weight for the competitor (which is previously compiled in past if/then loop). Note, I do not have it currently trying to print the competitor weight.
I believe I am on the right track for this, but for some reason, the numbers printed, after calling the sort method, are not correct. If you could tell me what I am doing wrong, that would be greatly helpful. Thanks.
import java.io.*;
import java.util.Scanner;
public class Project8
{
public static void main(String[] args)
throws FileNotFoundException
{
Scanner inF = new Scanner(new File("data7.txt"));
PrintWriter outF = new PrintWriter(new File("pro7out.txt"));
int [] arrayNum = new int[7];
int [] sortedNum = new int[7];
double [] arrayWeight = new double[7];
int place, firstplace, lastplace;
double weight;
String line;
String entries[];
outF.printf("My name - Project 7: 4/10/18%nResults of the Rocking JR Fishing Contest%n");
outF.printf("Competitor Total%n Number Weight%n");
for (int m = 0; m < 7; m++)
{
arrayNum[m] = m + 1;
}
while (inF.hasNextLine())
{
line = inF.nextLine();
entries = line.split(" +");
place = Integer.parseInt(entries[0]);
weight = Double.parseDouble(entries[1]);
if (place == 1)
arrayWeight[0] += weight;
else if (place == 2)
arrayWeight[1] += weight;
else if (place == 3)
arrayWeight[2] += weight;
else if (place == 4)
arrayWeight[3] += weight;
else if (place == 5)
arrayWeight[4] += weight;
else if (place == 6)
arrayWeight[5] += weight;
else
arrayWeight[6] += weight;
}
for (int k = 0; k < 7; k++)
outF.printf("%5d %15.2f%n", arrayNum[k], arrayWeight[k]);
firstplace = first(arrayNum, arrayWeight);
lastplace = last(arrayNum, arrayWeight);
sortedNum = sort(arrayNum, arrayWeight);
outF.printf(" Winner is%n %d %3.2f%n", firstplace, arrayWeight[firstplace-1]);
outF.printf(" Not as successful%n %d %3.2f%n", lastplace, arrayWeight[lastplace-1]);
for (int k = 0; k < 7; k++)
outF.printf("%d", sortedNum[k]);
outF.printf(" Contest Over%n");
inF.close();
outF.close();
}
public static int first(int number[], double weight[])
{
int firstplace=0;
double max=0;
for (int k = 0; k < 7; k++)
{
if (weight[k] > max)
{
max = weight[k];
firstplace = number[k];
}
}
return firstplace;
}
public static int last(int number[], double weight[])
{
int lastplace=0;
double minimum=weight[0];
for (int k = 0; k < 7; k++)
{
if (weight[k] < minimum)
{
minimum = weight[k];
lastplace = number[k];
}
}
return lastplace;
}
public static int[] sort(int number[], double weight[])
{
int n = number.length;
int tempNum = 0;
for (int i = 0; i < n; i++)
{
for (int j = 1; j < (n-1); j++)
{
if (weight[j - 1] < weight[j])
{
tempNum = number[j - 1];
number[j - 1] = number[j];
number[j] = tempNum;
}
}
}
return number;
}
}
I am solving a problem on hackerrank
Hacker Rank ICPC Team Problem
I have created the following code as solution for problem.
import java.math.BigInteger;
import java.util.Scanner;
public class ACMICPCTeam {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
int n=sc.nextInt(),m=sc.nextInt(),count=0,maxCount=0,teams=0;
sc.nextLine();
String subjectArray[]=new String[n];
for(int i=0;i<n;i++){
subjectArray[i]=sc.nextLine();
}
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
String temp=""+(new BigInteger(subjectArray[i]).add(new BigInteger(subjectArray[j])));
//System.out.println(temp);
count=temp.replace("0","").length();
if(count>maxCount)
{
maxCount=count;
teams=1;
}
else if(count==maxCount)
{
teams++;
}
}
}
System.out.println(maxCount);
System.out.println(teams);
sc.close();
}
}
So what I am trying to do is I am adding the two teams subjects and I am counting non-zeros of resultant string. The highest count is number of subjects and the occurrence of highest counts are teams which know max number of subject. Even after spending a lot time I am not able to any better solution than this one still I am facing time out as it is not efficient.
I have gone through forum of the question but it was of no help.
Don't use string logic for this.
Parse the string into a BitSet, before entering your loops, i.e. as you read them.
Then use methods or(BitSet set), and cardinality().
I just completed challenge doing that. No timeouts.
Your solution is not optimal you should try something better.
You can utilize BigInteger method or BitSet class to make it easy.
For forming a team you have to use bitwise OR
Here are solutions--
// 1st approach
static int[] acmTeam(String[] topic) {
int n = topic.length;
BigInteger[] bi = new BigInteger[n];
for (int i = 0; i < n; i++)
bi[i] = new BigInteger(topic[i], 2);
int maxTopic = 0;
int teamCount = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
BigInteger iuj = bi[i].or(bi[j]);
int bitCount = iuj.bitCount();
if (bitCount > maxTopic) {
maxTopic = bitCount;
teamCount = 1;
} else if (bitCount == maxTopic) {
teamCount++;
}
}
}
int result[] = { maxTopic, teamCount };
return result;
}
// 2nd approach--using java BitSet class
static int[] acmTeamUsingBitSet(String[] topic) {
int teamCount = 0, maxTopic = 0;
int size = topic.length;
BitSet[] bitset = new BitSet[size];
for (int i = 0; i < size; i++) {
BigInteger b1 = new BigInteger(topic[i], 2);
bitset[i] = BitSet.valueOf(b1.toByteArray());
}
for (int i = 0; i < size - 1; i++) {
BitSet bitset1 = bitset[i];
for (int j = i + 1; j < size; j++) {
BitSet bitset2 = bitset[j];
BitSet tmpset = new BitSet();
tmpset.or(bitset1);
tmpset.or(bitset2);
if (tmpset.cardinality() > maxTopic) {
maxTopic = tmpset.cardinality();
teamCount = 1;
} else if (maxTopic == tmpset.cardinality()) {
teamCount++;
}
}
}
int result[] = { maxTopic, teamCount };
return result;
}
You can refer this link for a detailed video explanation.
I got good result using Java 8.
static int[] acmTeam(String[] topic) {
List<List<Integer>> res = IntStream.range(0, topic.length)
.mapToObj(s -> IntStream.range(0, topic[s].length()).boxed()
.collect(Collectors.groupingBy(i -> topic[s].charAt(i))))
.map(m -> m.get('1'))
.collect(toList());
long maxTopic = 0;
int teamCount = 0;
for (int i = 0; i < res.size(); i++) {
for (int j = i + 1; j < res.size(); j++) {
long topics = Stream.concat(res.get(i).stream(), res.get(j).stream()).distinct().count();
if (topics > maxTopic) {
maxTopic = topics;
teamCount = 1;
} else if (topics == maxTopic) {
teamCount++;
}
}
}
return new int[]{(int) maxTopic, teamCount};
}
For an assignment I am doing for one of my classes, we have to implement a Sieve of Eratosthenes. I have tried seven times to get a code that works and have tried incorporating numerous solutions I've researched. I finally have one that will output numbers. Unfortunately, it prints both composite and prime numbers, and doesn't print 2.
My code is as follows:
public class EratosthenesSieveAttempt6 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int limit;
System.out.print("Please enter the highest number to check "
+ "(number must be greater than 2): ");
limit = keyboard.nextInt();
while (limit <= 2){
System.out.println("Error - number must be greater than 2.");
System.out.println("Please enter the highest number to check: ");
limit = keyboard.nextInt();
}
boolean[] numbers = new boolean[limit + 1];
int newPrime = 2;
for(int i = 0; i < limit + 1; i++){
numbers[i] = true;
}
for(int j = 1; j < limit + 1; j++) {
if (j % 2 == 0) {
numbers[j] = false;
}
for(int k = j + 1; k < limit + 1; k++) {
if(numbers[k] == true){
j = k;
System.out.println(k);
}
}
}
}
}
I'm suspecting that there is a problem with my loops. I fixed the i and j variables for my first two loops so that it would print out from 2 onward, the problem seems to be that it's not marking the composite numbers as false after I've initialized the array to true.
Thank you in advance for your help.
Here's an implementation of the Sieve of Eratosthenes I wrote the other day:
import java.util.BitSet;
public static BitSet composite(int max) {
BitSet composite = new BitSet(max);
max = composite.size();
for (int i = 4; i < max; i += 2) composite.set(i, true);
for (int i = 9; i < max; i += 6) composite.set(i, true);
int p = 5;
while (p*p < max) {
if (!composite.get(p)) {
for (int i = p*p; i < max; i += p*2) composite.set(i, true);
}
p += 2;
if (p*p >= max) break;
if (!composite.get(p)) {
for (int i = p*p; i < max; i += p*2) composite.set(i, true);
}
p += 4;
}
return composite;
}
Notes:
BitSet allocates 64-bit words, so the size may be larger than you requested (for example, if you ask it to go up to 1000, it will go up to 1024; that's the reason for max = composite.size() near the top)
Gets the 2's, 3's out of the way explicitly, and then
Relies on the fact that all primes larger than 3 are congruent to either 1 or 5 mod 6; this is the reason the final loop alternates between adding 2 and 4
It returns a BitSet that tells you which numbers are composite. One way to extract just the primes from it would be:
public static int[] primes(BitSet composite) {
int size = composite.size() - 2 - composite.cardinality();
int[] primes = new int[size];
int index = 0;
for (int i = 2; i < composite.size(); i++) {
if (!composite.get(i)) primes[index++] = i;
}
return primes;
}
I have made this program using array concept in java. I am getting Exception as ArrayIndexOutOfBound while trying to generate product.
I made the function generateFNos(int max) to generate factors of the given number. For example a number 6 will have factors 1,2,3,6. Now,i tried to combine the first and the last digit so that the product becomes equal to 6.
I have not used the logic of finding the smallest number in that array right now. I will do it later.
Question is Why i am getting Exception as ArrayIndexOutOfBound? [i couldn't figure out]
Below is my code
public class SmallestNoProduct {
public static void generateFNos(int max) {
int ar[] = new int[max];
int k = 0;
for (int i = 1; i <= max; i++) {
if (max % i == 0) {
ar[k] = i;
k++;
}
}
smallestNoProduct(ar);
}
public static void smallestNoProduct(int x[]) {
int j[] = new int[x.length];
int p = x.length;
for (int d = 0; d < p / 2;) {
String t = x[d++] + "" + x[p--];
int i = Integer.parseInt(t);
j[d] = i;
}
for (int u = 0; u < j.length; u++) {
System.out.println(j[u]);
}
}
public static void main(String s[]) {
generateFNos(6);
}
}
****OutputShown****
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
at SmallestNoProduct.smallestNoProduct(SmallestNoProduct.java:36)
at SmallestNoProduct.generateFNos(SmallestNoProduct.java:27)
at SmallestNoProduct.main(SmallestNoProduct.java:52)
#Edit
The improved Code using array only.
public class SmallestNoProduct {
public static void generateFNos(int max) {
int s = 0;
int ar[] = new int[max];
int k = 0;
for (int i = 1; i <= max; i++) {
if (max % i == 0) {
ar[k] = i;
k++;
s++;
}
}
for (int g = 0; g < s; g++) {
System.out.println(ar[g]);
}
smallestNoProduct(ar, s);
}
public static void smallestNoProduct(int x[], int s) {
int j[] = new int[x.length];
int p = s - 1;
for (int d = 0; d < p;) {
String t = x[d++] + "" + x[p--];
System.out.println(t);
int i = Integer.parseInt(t);
j[d] = i;
}
/*for (int u = 0; u < j.length; u++) {
System.out.println(j[u]);
}*/
}
public static void main(String s[]) {
generateFNos(6);
}
}
Maybe it better:
public class SmallestNoProduct {
public static int smallest(int n) {
int small = n*n;
for(int i = 1; i < Math.sqrt(n); i++) {
if(n%i == 0) {
int temp = Integer.parseInt(""+i+""+n/i);
int temp2 = Integer.parseInt(""+n/i+""+i);
temp = temp2 < temp? temp2: temp;
if(temp < small) {
small = temp;
}
}
}
return small;
}
public static void main(String[] args) {
System.out.println(smallest(6)); //6
System.out.println(smallest(10)); //25
System.out.println(smallest(100)); //205
}
}
Problem lies in this line
String t=x[d++]+""+x[p--];
x[p--] will try to fetch 7th position value, as p is length of array x i.e. 6 which results in ArrayIndexOutOfBound exception. Array index starts from 0, so max position is 5 and not 6.
You can refer this question regarding postfix expression.
Note: I haven't checked your logic, this answer is only to point out the cause of exception.
We are unnecessarily using array here...
below method should work....
public int getSmallerMultiplier(int n)
{
if(n >0 && n <10) // if n is 6
return (1*10+n); // it will be always (1*10+6) - we cannot find smallest number than this
else
{
int number =10;
while(true)
{
//loop throuogh the digits of n and check for their multiplication
number++;
}
}
}
int num = n;
for(i=9;i>1;i--)
{
while(n%d==0)
{
n=n/d;
arr[i++] = d;
}
}
if(num<=9)
arr[i++] = 1;
//printing array in reverse order;
for(j=i-1;j>=0;j--)
system.out.println(arr[j]);
I'm writing a program which is supposed to find the 25 top numbers in a large array using threads. My algorithm seems to work fine, however when comparing the result to an Arrays.sort-ed version of the original array, it seems like my top 25-list misses some of the numbers. I really hate posting this much code in a question, but I'm completely stuck on this, and has been for a couple of hours now. I'd love some help figuring out what's wrong. Here are my classes:
Main.java
import java.util.Arrays;
import java.util.Random;
public class Main {
public static void main(String[] args) {
final int NUM_THRS = 4;
int[] numbers = new int[500];
Random generator = new Random(500);
for(int i = 0; i < numbers.length; i++) {
numbers[i] = Math.abs(generator.nextInt());
}
Thread[] thrs = new Thread[NUM_THRS];
NumberThread[] nthrs = new NumberThread[NUM_THRS];
long startTime = System.currentTimeMillis();
for(int i = 0; i < thrs.length; i++) {
int start = getStart(i, thrs.length, numbers.length);
int stop = getStop(i, thrs.length, numbers.length);
nthrs[i] = new NumberThread(numbers, start, stop);
thrs[i] = new Thread(nthrs[i]);
thrs[i].start();
}
for (int i = 0; i < thrs.length; i++) {
try {
thrs[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int[] top = new int[25];
int[] indices = new int[NUM_THRS];
for (int i = 0; i < indices.length; i++) {
indices[i] = 24;
}
for(int i = 0; i < top.length; i++) {
top[i] = getMax(nthrs, indices);
}
for (int i = 0; i < top.length; i++) {
System.out.println(top[i]);
}
}
public static int getMax(NumberThread[] thrs, int[] indices) {
int maxNum = 0;
int maxIdx = 0;
for(int i = 0; i < indices.length; i++) {
if(indices[i] >= 0) {
if(thrs[i].topNums[indices[i]] > maxNum) {
maxNum = thrs[i].topNums[indices[i]];
maxIdx = i;
}
}
}
System.out.println("iterate");
indices[maxIdx] = indices[maxIdx]-1;
return maxNum;
}
public static int getStart(int i, int total, int len) {
return i*len/total;
}
public static int getStop(int i, int total, int len) {
if(i != total-1) {
return (i+1)*len/total;
}
return len-1;
}
}
NumberThread.java
public class NumberThread implements Runnable {
int start, stop;
int[] numbers;
int[] topNums;
public NumberThread(int[] numbers, int start, int stop) {
this.numbers = numbers;
this.start = start;
this.stop = stop;
this.topNums = new int[25];
System.out.println(start + " " + stop);
}
#Override
public void run() {
for (int i = start; i <= stop; i++) {
inner: for (int j = topNums.length-1; j > 0; j--) {
if(numbers[i] > topNums[j]) {
topNums[j] = numbers[i];
break inner;
}
}
}
}
}
The numbers printed after main are not the same as the top numbers when I Arrays.sort the numbers-array and print the top 25. Some numbers seem to be missing.
Thanks a lot in advance.
I think that your NumberThread classes Run method isn't doing what it should do. It needs to find the 25 largest numbers in the partition you assign to it, for example if the array you are searching was already sorted then the 25 largest numbers could all be in 1 partition but what its's actually doing is overwriting the first number it finds that's smaller than the current number so you end up with less than 25 numbers and they might not be the largest.
For example consider the sequence 98 99 1 2 3... 98 would get written to topNums[19] but then overwritten with 99.
I'm also not sure about the getMax function, it seems to be trying to merge the different topNums arrays together; however the arrays aren't sorted so I don't see how it can work.