I am currently attempting problem 3 of Euler's Problems and I have run into the problem where when the below code is compiled, all I get is "1" as output even though the for loop makes it run over multiple times. I have lowered the number down to 30 to try to find the problem but I have not found it. Looking at other solutions, my solution's logic is exactly the same.
public class eulerproblem3
{
public static void main(String[]args)
{
int current = 1;
for (int test=1;test==30;test++)
{
if ((30%test)==0)
{
boolean a = testPrime(test);
if ((a==true)&&(test==current))
{
System.out.println(current);
}
}
}
}
private static boolean testPrime(long test1)
{
for(long ref=2; test1==ref; ref++)
{
if ((test1%ref)==0)
{
return false;
}
}
return true;
}
}
The conditions of your fors will be always false. You probably want something like
for (int test = 1; test < 30; test++)
Related
The below code works fine for attached input.
public class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
return wordBreakMemo(s, new HashSet<>(wordDict), 0, new Boolean[s.length()]);
}
private boolean wordBreakMemo(String s, Set<String> wordDict, int start, Boolean[] memo) {
if (start == s.length()) {
return true;
}
if (memo[start] != null) {
return memo[start];
}
for (int end = start + 1; end <= s.length(); end++) {
if (wordDict.contains(s.substring(start, end)) && wordBreakMemo(s, wordDict, end, memo)) {
return memo[start] = true;
}
}
return memo[start] = false;
}
}
But when I change the local variables to global as below, my code take longer to execute, resulting in 'Time Limit Exceeded' on LeetCode.
class Solution {
HashSet<String> set;
String s;
Boolean dp[];
public boolean wordBreak(String s, List<String> wordDict) {
set=new HashSet();
set.addAll(wordDict);
this.s=s;
dp=new Boolean[s.length()];
return wordMemo(0);
}
public boolean wordMemo(int start)
{
if(start==s.length())
return true;
if(dp[start]!=null)
return dp[start];
for(int i=start+1; i<=s.length(); i++)
{
if(set.contains(s.substring(start, i)) && wordMemo(i))
{
dp[start]=true;
return true;
}
}
return false;
}
}
Input:
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"
["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]
Can someone please explain what is happening around here?
Global variables don't have slower fetch times, no.
Whenever you get Time Limit Exceeded in a coding challenge you should assume you have a a flawed or buggy algorithm or data structure. It's never micro factors like fetch times or access modifiers or the language you've chosen. Even if you could speed up your program 10% with better memory access patterns or 100% by switching from Python to C, you're probably off by 10,000% or 10,000,000%, not 100%. That's how bad it can be when your program is accidentally O(n2) or O(2n) when the challenge designers expect O(n).
Here, the first program has:
return memo[start] = false;
While the second one has just:
return false;
It never memoizes false results. There are a lot more repeated computations, enough to kill the algorithm's Big-O time complexity.
This is supposed to loop 24 times; it does not, and I'm pretty confused as to why. Please help me various Kenobis out there :
private boolean simpleMove(Board bd)
{
int b = rn.nextInt(3);
for (int i = 0; i < 24; i++) {
if (bd.isVacant(i) && rul.isLegalMove(tigerLocs[b], i)) {
bd.swap(tigerLocs[b],i);
bd.setTiger(i);
tigerLocs[b] = i;
System.out.println(i);
return true;
}
else {
System.out.println(i);
}
}
System.out.println("invalid");
return false;
As the comments point out your loop will execute a maximum of 24 times.
But the return statement inside the if statement may cause it to return 'early'.
It looks like it's some kind of board game thing.
The board appears to have 24 'squares' and it makes the first legal move and returns true.
If it fails to find a legal move, it returns false.
I can't confirm the logic overall but that rationale seems sound:
If there's a move available, take it and return true.
If no move is available, make no move and return false.
If you expected it to continue, even after finding a "valid" move, then simply store the fact that a valid move has been found. This can be done in a separate boolean variable:
private boolean simpleMove(Board bd) {
int b = rn.nextInt(3);
boolean valid = false; // until proven otherwise below
for (int i = 0; i < 24; i++) {
if (bd.isVacant(i) && rul.isLegalMove(tigerLocs[b], i)) {
bd.swap(tigerLocs[b],i);
bd.setTiger(i);
tigerLocs[b] = i;
valid = true;
}
System.out.println(i); // why output HERE when we have a return value?
}
if (!valid) {
System.out.println("invalid"); // why output HERE when we have a return value?
}
return valid;
}
It's unclear if multiple "valid" moves could be found, and whether that would be a problem when you "swap" or not. If there is only ever one possible move, then there would be no need to continue iterating with the for loop; simply return in the body like you were doing.
Recently, I tried to write a Java program which searches for the minimum of an array.
I tried to write it in a different way, I know there are more simple ways to do that but I want to know why my program does not work.
Here is the source code :
public int minimum(int [] t) {
int min,i,j;
i=j=t.length/2;
min=t[t.length/2];
while(j!=0 || i!=t.length-1) {
while( t[i]>=min) {
i++;
if(i==t.length) {
i=t.length-1;
continue;
}
}
while(t[j]>=min) {
j--;
if(j==-1) {
j=0;
continue;
}
}
if(t[i]<=min && t[j]<=min) {
if(t[i]<=t[j]) min=t[i];
else min=t[j];
}
}
return min;
}
Thanks.
Before you read the answer you should try debugging your code to figure this out by yourself.
I think your code loops infinitely in one of those inner while loops because the end condition
if(i==t.length) {
i=t.length-1;
continue;
}
only resets the i one step back and the continue restarts the while loop. You probably meant to have the break keyword there instead of the continue in which case your code will continue with the other inner while loop.
there is some logic errors in my code , and it get infinitely going through the two loops , i fixed the loops by changing continue with break and i modify the last condition by setting || instead of && (that was a logic mistake), and it works now .
thanks guys.
here is the new source code:
public int minimum(int [] t) {
int min,i,j;
i=j=t.length/2;
min=t[t.length/2];
while(j!=0 || i!=t.length-1) {
while( t[i]>=min) {
i++;
if(i==t.length) {
i=t.length-1;
break;
}
}
while(t[j]>=min) {
j--;
if(j==-1) {
j=0;
break;
}
}
if(t[i]<=min || t[j]<=min) {
if(t[i]<=t[j]) min=t[i];
else min=t[j];
}
}
return min;
}
TLDR at bottom
I've been assigned a programming project at school to build a percolation model and i've come across an issue which has given me quite some confusion. First off, we were supposed to build an api to run a percolation simulation
public class Percolation{
private int grid[][];
public int size;
QuickFindUF unionFind;
//WeightedQuickUnionUF unionFind;
public Percolation(int n)
{
if(n<1){
throw new IllegalArgumentException ("grid must be larger than 0");
}
grid=new int[n][n];
size=n;
unionFind=new QuickFindUF(size*size);
//unionFind=new WeightedQuickUnionUF(size*size);
//initially set all to blocked
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
grid[i][j]=1;
}
}
}
public void open(int x, int y)
{
grid[x][y]=0;
//Check below to see if you can
//if you are not on the bottom row
if(y>0)
{
if(grid[x][y]==0 && grid[x][y-1]==0){unionFind.union(x+y*size,x+(y-1)*size);}
}
//check to see to the right (x->)
if(x<size-1){
if(grid[x][y]==0 && grid[x+1][y]==0){unionFind.union(x+y*size,x+1+y*size);}
}
//check if can union to the left
if(x>0)
{
if(grid[x][y]==0 && grid[x-1][y]==0){unionFind.union(x+y*size,x-1+y*size);}
}
//check for above
if(y<size-1){
if(grid[x][y]==0 && grid[x][y+1]==0){unionFind.union(x+y*size,x+(y+1)*size);}
}
}
public boolean isOpen(int x, int y)
{
if(x>=size || y>=size){return false;}
if(grid[x][y]==0){return true;}
return false;
}
public boolean isFull(int x, int y)
{
if(x>=size || y>=size){return false;}//if input is out of bounds
for(int i=0;i<size;i++){
if(unionFind.connected(x+y*size,i+((size-1)*size)))
return true;
}
return false;
}
public boolean percolates()
{
for(int i=0;i<size;i++){
for(int j=0;j<size;j++){
if(unionFind.connected(i,(size-1)*size+j)){
//System.out.println(i+" "+((size-1)*size+j));
return true;
}
}
}
return false;
}
}
Now, the book kindly provides the quickfindUF and WeightedQuickUnionUF. All the classmates i've talked to have gotten the expected results when timing with a PercolationStats class which we've been instructed to make but my results very greatly. Here's the class
class PercolationStats{
private Percolation perc;
private double[] array;
private int expCount;
public PercolationStats(int gridSize, int numOfExperiments){
if(gridSize <= 0 || numOfExperiments <=0)
throw new IllegalArgumentException("gridSize and numOfExperiments needs to be more than 0");
array=new double[numOfExperiments];
expCount=numOfExperiments;
for(int i=0;i<numOfExperiments;i++){
perc=new Percolation(gridSize);
int count=0;
while(!perc.percolates()){
int x=StdRandom.uniform(gridSize),y=StdRandom.uniform(gridSize);
if(!perc.isOpen(x,y)){
perc.open(x,y);
count++;
}
}
array[i]=(double) count/(gridSize*gridSize);
}
}
public double mean(){
return StdStats.mean(array);
}
public double stddev(){
return StdStats.stddev(array);
}
public double confidenceLo(){
return mean() - ((1.96 * stddev()) / Math.sqrt(expCount));
}
public double confidenceHi(){
return mean()+((1.96 * stddev()) / Math.sqrt(expCount));
}
public static void main(String[] args){
Stopwatch timer=new Stopwatch();
PercolationStats percStats=new PercolationStats(200,100);
System.out.println("mean: "+ percStats.mean() +"stddev: "+percStats.stddev()+" confidence Lo: "+percStats.confidenceLo()+" confidence hi: "+percStats.confidenceHi());
System.out.println(timer.elapsedTime());
percStats=new PercolationStats(200,100);
System.out.println("mean: "+ percStats.mean() +"stddev: "+percStats.stddev()+" confidence Lo: "+percStats.confidenceLo()+" confidence hi: "+percStats.confidenceHi());
percStats=new PercolationStats(2,100000);
System.out.println("mean: "+ percStats.mean() +"stddev: "+percStats.stddev()+" confidence Lo: "+percStats.confidenceLo()+" confidence hi: "+percStats.confidenceHi());
}
}
When I run this with the QuickFindUF, at percStats(200,100), it takes me about 7 seconds, and if I run it at the same 200,100 with WeightedQuickUnionUF, It takes about 50+ seconds?? I was quite certain that the weighted quick union was supposed to be faster, and it's not just a matter of getting unlucky with my horrendous worst case random number generator. I ran it quite a few times and still the results were about the same and I've been staring here at the code for quite a while and can't figure out why my code is so wrong..
TLDR
Correct results, incorrect timing. Slower api is faster for some reason and I can't figure out why. QuickFindUF faster than WeightedQuickUnionUF. (about 7-8 times faster). What am I doing wrong?
Haha I'm dumb. I saw online that others were using a virtual top so I added one and now it works fine :P
I just discovered the project euler website, I have done challenges 1 and 2 and have just started number 3 in java... here is my code so far:
import java.util.ArrayList;
public class IntegerFactorise {
private static int value = 13195;
private static ArrayList<Integer> primeFactors = new ArrayList<Integer>();
private static int maxPrime = 0;
/**
* Check whether a give number is prime or not
* return boolean
*/
public static boolean isPrimeNumber(double num) {
for(int i = 2; i < num; i++) {
if(num % i == 0) {
return false;
}
}
return true;
}
/*Multiply all of the prime factors in the list of prime factors*/
public static int multiplyPrimeFactors() {
int ans = 1;
for(Integer i : primeFactors) {
ans *= i;
}
return ans;
}
/*Find the maximum prime number in the list of prime numbers*/
public static void findMaxPrime() {
int max = 0;
for(Integer i : primeFactors) {
if(i > max) {
max = i;
}
}
maxPrime = max;;
}
/**
* Find all of the prime factors for a number given the first
* prime factor
*/
public static boolean findPrimeFactors(int num) {
for(int i = 2; i <= num; i++) {
if(isPrimeNumber(i) && num % i == 0 && i == num) {
//could not possibly go further
primeFactors.add(num);
break;
}
else if(isPrimeNumber(i) && num % i == 0) {
primeFactors.add(i);
findPrimeFactors(num / i);
}
}
int sumOfPrimes = multiplyPrimeFactors();
if(sumOfPrimes == value) {
return true;
}
else {
return false;
}
}
/*start here*/
public static void main(String[] args) {
boolean found = false;
for(int i = 2; i < value; i++) {
if(isPrimeNumber(i) && value % i == 0) {
primeFactors.add(i);
found = findPrimeFactors(value / i);
if(found == true) {
findMaxPrime();
System.out.println(maxPrime);
break;
}
}
}
}
}
I am not using the large number they ask me to use yet, I am testing my code with some smaller numbers, with 13195 (their example) i get down to 29 in this bit of my code:
else if(isPrimeNumber(i) && num % i == 0) {
primeFactors.add(i);
findPrimeFactors(num / i);
}
}
int sumOfPrimes = multiplyPrimeFactors();
if(sumOfPrimes == value) {
return true;
}
It gets to the break statement then finally the check and then the return statement.
I am expecting the program to go back to the main method after my return statement, but it jumps up to:
findPrimeFactors(num / i);
and tries to finish the iteration...I guess my understanding is a flawed here, could someone explain to me why it is behaving like this? I can't wait to finish it of :) I'll find a more efficient way of doing it after I know I can get this inefficient one working.
You are using recursion, which means that a function will call itself.
So, if we trace what your function calls are when you call return, we will have something like that:
IntegerFactorise.main()
|-> IntegerFactorise.findPrimeFactors(2639)
|-> IntegerFactorise.findPrimeFactors(377)
|-> IntegerFactorise.findPrimeFactors(29) -> return true;
So, when you return in the last findPrimeFactors(), you will only return from this call, not from all the stack of calls, and the execution of the previous findPrimeFactors() will continue just after the point where you called findPrimeFactors().
If you want to return from all the stack of calls, you have to modify your code to do something like that:
else if(isPrimeNumber(i) && num % i == 0) {
primeFactors.add(i);
return findPrimeFactors(num / i);
}
So that when the last findPrimeFactors() returns, all the previous findPrimeFactors() which called it will return too.
I think the problem is that you are ignoring the return value from your recursive call to findPrimeFactors().
Let's walk through this. We start with the initial call to findPrimeFactors that happens in main. We then enter the for loop as it's the first thing in that method. Now let's say at some point we get into the else statement and thus recursively call frindPrimeFactors(num / i). This will suspend the looping, but as this recursive call starts to run you enter the for loop again (remember, the previous loop is merely paused and not finished looping yet). This time around you encounter the break, which allows this recursive call to finish out, returning true of false. When that happens you are now back to the original loop. At this point the original loop continues even if the recursive call returned true. So, you might try something like this:
if (findPrimeFactors(num / i))
return true;
I'm assuming that you need to continue looping if the recursive call returned false. If you should always finish looping upon return (whether true or false) then try this:
return findPrimeFactors(num / i);