If else statement not checking all the else statements - java

SO im making a program the will solve a maze recursively and im having problems with my
if else statements. I had a similar problem in a different part of my code and i solved it by just taking out all the else's and just having a bunch of if statements. But now i need it the stop searching after it finds the correct way to go.
public static void solveMaze(int ROW, int COL){
int isFinished = 0;
//ROW COL
//set up base case. find end if possible to get in 1 move then end
if(drawArray[ROW][COL+1] == ' '){
if(drawArray[ROW][COL+2] == 'E'){
isFinished = 1;
move(ROW,COL,ROW,COL+2);
}
}
if(drawArray[ROW][COL-1] == ' '){
if(drawArray[ROW][COL-2] == 'E'){
isFinished = 1;
move(ROW,COL,ROW,COL-2);
}
}
if(drawArray[ROW+1][COL] == ' '){
if(drawArray[ROW+2][COL] == 'E'){
isFinished = 1;
move(ROW,COL,ROW+2,COL);
}
}
if(drawArray[ROW-1][COL] == ' '){
if(drawArray[ROW-2][COL] == 'E'){
isFinished = 1;
move(ROW,COL,ROW-2,COL);
}
}
//find first open cell and choose it
int foundOpen = 0;
if(isFinished == 0){
if(drawArray[ROW][COL+1] == ' ' && drawArray[ROW][COL+2] != '*'){
drawArray[ROW][COL+2] = '*';
prevCol = COL;
prevRow = ROW;
COL+= 2;
foundOpen = 1;
}
else if(drawArray[ROW+1][COL] == ' ' && drawArray[ROW+2][COL] != '*'){
drawArray[ROW+2][COL] = '*';
prevCol = COL;
prevRow = ROW;
ROW+= 2;
foundOpen = 1;
}
else if(drawArray[ROW][COL-1] == ' ' && drawArray[ROW][COL-2] != '*'){
drawArray[ROW][COL-2] = '*';
prevCol = COL;
prevRow = ROW;
ROW-= 2;
foundOpen = 1;
}
else if(drawArray[ROW-1][COL] == ' ' && drawArray[ROW-2][COL] != '*'){
drawArray[ROW-2][COL] = '*';
prevCol = COL;
prevRow = ROW;
ROW-= 2;
foundOpen = 1;
}
}
//i have two recursive voids so this is chosing between them
if(foundOpen == 1){
move(prevRow,prevCol,ROW,COL);
solveMaze(ROW,COL);}
else if (foundOpen == 0 && isFinished == 0)
wrongChoice(ROW, COL);
}
SO basically this part of the program checks to see first if the end is near and if it is basically finish. I use to have if else statements for the first part to but i wouldnt work and the only way i could fix it was by taking out the else's. So in one maze that i have to solve the first move should be COL-1 == ' ' and COL-2 != '*'. so that if statement should happen but it doesnt. I put in a bunch of println statements to check where it was going off and isFInished == 0 so it starts into that if statement but then something goes wrong and nothing solution is found so wrongChoice is called. Im prety new to java and recursion so i might be missing something obvios.

boolean isFinished = true;
if (drawArray[ROW][COL+1] == ' ' && drawArray[ROW][COL+2] == 'E') {
move(ROW,COL,ROW,COL+2);
} else if (drawArray[ROW][COL-1] == ' ' && drawArray[ROW][COL-2] == 'E') {
move(ROW,COL,ROW,COL-2);
} else if (drawArray[ROW+1][COL] == ' ' && drawArray[ROW+2][COL] == 'E') {
move(ROW,COL,ROW+2,COL);
} else if (drawArray[ROW-1][COL] == ' ' && drawArray[ROW-2][COL] == 'E') {
move(ROW,COL,ROW-2,COL);
} else {
isFinished = false;
}
int foundOpen = 0;
if (!isFinished) {
That should do.
If you do this kind of looking at naybors more often:
static final int[][] naybors = {
{ 0, 1 },
{ 0, -1 },
{ 1, 0 },
{ -1, 0 },
};
boolean isFinished = false;
for (int[] nb : naybors) {
if (drawArray[ROW + nb[0]][COL + nb[1]] == ' '
&& drawArray[ROW + 2*nb[0]][COL + 2*nb[1]] == 'E') {
move(ROW, COL, ROW + 2*nb[0], COL + 2*nb[1);
isFinished = true;
break;
}
}
Also saw:
else if(drawArray[ROW][COL-1] == ' ' && drawArray[ROW][COL-2] != '*'){
drawArray[ROW][COL-2] = '*';
prevCol = COL;
prevRow = ROW;
//Wrong: ROW-= 2;
COL -= 2; // Good?
foundOpen = 1;
}

you could System.out.print and check where you want it to stop then use #mserioli suggestion which will work. good luck

Related

How to reverse for loop?

I have a method with some logic
first it looked like:
static boolean checkWin(char dot) {
if (map[0][0] == dot && map[0][1] == dot && map[0][2] == dot) {
return true;
}
//more code
if (map[0][2] == dot && map[1][1] == dot && map[2][0] == dot) {
return true;
}
return false;
}
With loops I refactored the method:
static boolean checkWin(char dot) {
for (int i = 0; i <map.length ; i++) {
for (int j = 0; j < map[i].length; j++) {
if (map[0][i] == dot && i == 2) {
return true;
}
if (map[1][i] == dot && i == 2) {
return true;
}
if (map[2][i] == dot && i == 2) {
return true;
}
if (map[i][0] == dot && i == 2) {
return true;
}
if (map[i][1] == dot && i == 2) {
return true;
}
if (map[i][2] == dot && i == 2) {
return true;
}
if (map[i][i] == dot && i == 2) {
return true;
}
if (map[0][2] == dot && map[1][1] == dot && map[2][0] == dot) {
return true;
}
}
}
return false;
}
I have a problem with this line of code:
if (map[0][2] == dot && map[1][1] == dot && map[2][0] == dot)
return true;
}
I need to get map[i][?], ? should assume the value 2, 1 and 0 when i equals to 0, 1 and 2 respectively.
How can I achieve it?
Try to decrease it
for (int i = 2; i > = 0; i--) {
}
i will be 2 1 0
P.S
I think you missed 2 there
P.S
If I understand your question correctly, you need to have 2 1 0 inside loop without modifying for itself? In that case try:
for (int i = 3; i < 3; i++) {
... 2 - i
}

Simplify a given algebraic string. Output the simplified string without parentheses

The examples look like this, Input : "a-(b+c)" output "a-b-c", Input : "a-(a+b)" output "b"
I came up with this method, but the result for input: "a-(a+b)" is "a-a-b", which the correct one should be "b", how to improve that?
public String simplify(String str)
{
int len = str.length();
char res[] = new char[len];
int index = 0, i = 0;
Stack<Integer> s = new Stack<Integer> ();
s.push(0);
while (i < len) {
if (str.charAt(i) == '+') {
if (s.peek() == 1)
res[index++] = '-';
// If top is 0, append the same operator
if (s.peek() == 0)
res[index++] = '+';
} else if (str.charAt(i) == '-') {
if (s.peek() == 1)
res[index++] = '+';
else if (s.peek() == 0)
res[index++] = '-';
} else if (str.charAt(i) == '(' && i > 0) {
if (str.charAt(i - 1) == '-') {
// x is opposite to the top of stack
int x = (s.peek() == 1) ? 0 : 1;
s.push(x);
}
else if (str.charAt(i - 1) == '+')
s.push(s.peek());
}
else if (str.charAt(i) == ')')
s.pop();
else
res[index++] = str.charAt(i);
i++;
}
return new String(res);
}

How do I check if a position in my vector of vectors is out of bounds?

I have a vector of vectors filled with characters from a text file. It is essentially a simple outbreak simulator, with 'i' characters being infected, and 's' characters being susceptible to infection. The point is to run through the matrix and if it comes across an 'i', it then changes all 's' around it into an 'i'. I run into a problem when checking the elements around it due to checking positions out of the bounds on the edges of the matrix. Is there a way to check these bounds in my if statements?
Here is the code:
for (int i = 0; i < population.size(); i++) {
for(int j = 0; j < population[i].size(); j++) {
if(population[i][j] == 'i') {
if(population[i-1][j] == 's') {
population[i-1][j] = 'i';
}
if(population[i-1][j+1] == 's') {
population[i-1][j+1] = 'i';
}
if(population[i][j+1] == 's') {
population[i][j+1] = 'i';
}
if(population[i+1][j+1] == 's') {
population[i+1][j+1] = 'i';
}
if(population[i+1][j] == 's') {
population[i+1][j] = 'i';
}
if(population[i+1][j-1] == 's') {
population[i+1][j-1] = 'i';
}
if(population[i][j-1] == 's') {
population[i][j-1] = 'i';
}
}
}
}
Instead of directly referencing a particular array entry, you could do something like the following:
void checkForInfectionAndInfectIfNeeded(int i, int j) {
for (int row = -1; row <= 1; row++) {
for (int column = -1; column <=1; column++) {
infect(i + row, j + column);
}
}
}
void infect(int i, int j) {
if (i < 0 || i >= population.size() || j < 0 || j >= population[j].size()) {
return;
} else {
population[i][j] = 'i';
}
}
This way, the infect method is the only that checks the boundaries, and you replace your long list of manually checking the surrounding locations with two loops.

Own String parser java which solves mathematical equations wrote down in a string

I've wrote a method/function in Java which returns the result of a given basic equation. This equation will be given as a String and I think I got this method working but don't know why I need this one line of Code because this should work without it. After trying for more than an hour to solve it I gave up and hope you can give me an aswer.
Here the Code:
public static double format(String s) {
char[] c = s.toCharArray();
if(s.contains("(")) {
int openbrackets = 0;
for (int i = 0; i < s.length() - 2; i++) {
if (c[i] == '(') openbrackets++;
else if (c[i] == ')') {
openbrackets--;
if(openbrackets == 0) {
s = s.replace(s.substring(s.indexOf('('), i+1), ""+(format(s.substring(s.indexOf('(')+1, i))));
break;
}
}
}
}
if (s.contains("(")) { // String can still contains brackets
s = "" + format(s);
}
c = s.toCharArray();
for(int i = c.length-1; i >= 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
for(int i = s.length()-1; i > 0; i--) {
if(c[i] == '*') {
return format(s.substring(0, i)) * Double.parseDouble(s.substring(i+1, s.length()));
} else if (c[i] == '/') {
return format(s.substring(0, i)) / Double.parseDouble(s.substring(i+1, s.length()));
}
}
return s.equals("") ? 0 : Double.parseDouble(s); // I don't understand why I need to do this line
}
Description:
I don't know why I need this s.equals("") ? : because the String never should be empty however when I run it with this equation ((23)+(23-23-432-35-1-2-4231+2312+12323-(-3))*3/2) for example I get an error without it.
I need the parser to convert config Strings into Numbers for example when it comes to screenresolution. I know I can also use Libraries but I want to try these things by myself.
PS: Dont hate me just because I don't use libraries. I really tried to figure it out and I have fun doing it. I would just like to know why I have to write this little Codeline as I don't figure it out...
Edit: Error was a NumberFormatException as the Parsing got an empty String... Got my error now also the OverflowException which was mentioned in the comments...
EDIT: To everyone who MIGHT use something like this in the future:
Here the Code which actually works:
public static double format(String s) {
s = s.replace(" ", "");
s = s.replace("\t", "");
char[] c = s.toCharArray();
if(s.contains("(")) {
int openbrackets = 0;
for (int i = 0; i < s.length(); i++) {
if (c[i] == '(') openbrackets++;
else if (c[i] == ')') {
openbrackets--;
if(openbrackets == 0) {
s = s.replace(s.substring(s.indexOf('('), i+1), ""+(format(s.substring(s.indexOf('(')+1, i))));
break;
}
}
}
}
if (s.contains("(")) s = "" + format(s);
c = s.toCharArray();
for(int i = c.length-1; i > 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
for(int i = s.length()-1; i > 0; i--) {
if(c[i] == '*') {
return format(s.substring(0, i)) * Double.parseDouble(s.substring(i+1, s.length()));
} else if (c[i] == '/') {
return format(s.substring(0, i)) / Double.parseDouble(s.substring(i+1, s.length()));
}
}
return s.equals("") ? 0 : Double.parseDouble(s);
}
I'm fairly sure this is at least one location in your code where you pass a 0 length string to your format function:
c = s.toCharArray();
for(int i = c.length-1; i >= 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
Your loop counter in (int i = c.length-1; i >= 0; i--) will get decremented until it is 0 in value if there are no + or - values in the input string.
Then you call format(s.substring(0, i)) where i = 0 so I think this is one place where you will be passing a zero length/empty string to your function.
Please use a debugger and step through your code - not only would it teach you a valuable skill it would also probably give you the answer you're looking for.

How can I make this faster, without making it multi-threaded?

My program is working fine, in terms of output, but for some of my test cases it takes too long to find an answer (sometimes taking 18 seconds). I would like to know how I can improve the performance of my code.
What my code does:
It's a take on Pebble Solitaire. The user inputs n number of games and after that inputs a strings of length 23 that contains a combinations of only 'o' (pebble) and '-' (empty space). If there are 2 adjacent pebbles and an empty space on either side, ie (oo- OR -oo), then you remove the middle pebble and you swap other two pieces with each other, ex 'oo-' will turn into '--o'.
My current approach is pretty much an exhaustive approach where it tries out every possible move and results the move set with the least number of pebbles left.
I would like to know how I can improve this solution without making it multi-threaded.
Here is what I have:
package Pebble;
import java.util.Scanner;
public class PebbleSolitaire {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int numOfGames = Integer.parseInt(input.nextLine());
while (numOfGames > 0){
char[] values = input.nextLine().toCharArray();
long startTime = System.nanoTime();
System.out.println(solve(values));
System.out.println("Time to finish in ms: " + (System.nanoTime() - startTime) / 1000000);
numOfGames--;
}
input.close();
}
private static int solve(char[] game){
if(game != null && game.length == 0){
return -1;
}
int result = 0;
for (int i = 0; i < game.length; i++){
if(game[i] == 'o'){
result++;
}
}
//print(game);
for (int i = 0; i < game.length; i++ ){
char[] temp = new char[game.length];
copyArray(temp, game);
if (i-2 >= 0 && temp[i] == '-' && temp[i-2] == 'o' && temp[i-1] == 'o'){//move pebble forwards
temp[i-1] = temp[i-2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
copyArray(temp, game);
if(i+2 < temp.length && temp[i] == '-' && temp[i+1] == 'o' && temp[i+2] == 'o'){//move pebble backwards
temp[i+1] = temp[i+2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
}
return result;
}
private static void copyArray(char[] copy, char[] og){
for(int x = 0; x < copy.length; x++){
copy[x] = og[x];
}
}
private static void print(char[] c){
for(char ch: c){
System.out.print(ch);
}
System.out.println();
}
}
My sample input and output:
2
-o----ooo----o----ooo--
6
Time to finish in ms: 0
oooooooooo-ooooooooooo-
4
Time to finish in ms: 18149
EDIT: Would making this completely iterative drastically improve the performance?
Maybe you can improve this parte:
for (int i = 0; i < game.length; i++ ){
char[] temp = new char[game.length];
copyArray(temp, game);
if (i-2 >= 0 && temp[i] == '-' && temp[i-2] == 'o' && temp[i-1] == 'o'){//move pebble forwards
temp[i-1] = temp[i-2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
copyArray(temp, game);
if(i+2 < temp.length && temp[i] == '-' && temp[i+1] == 'o' && temp[i+2] == 'o'){//move pebble backwards
temp[i+1] = temp[i+2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
}
to:
for (int i = 0; i < game.length; i++ ){
char[] temp = null;
if (i-2 >= 0 && game[i] == '-' && game[i-2] == 'o' && game[i-1] == 'o'){//move pebble forwards
temp = new char[game.length];
copyArray(temp, game);
temp[i-1] = temp[i-2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
if(i+2 < game.length && game[i] == '-' && game[i+1] == 'o' && game[i+2] == 'o'){//move pebble backwards
if(temp == null) temp = new char[game.length];
copyArray(temp, game);
temp[i+1] = temp[i+2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
}
Basically, only creating and "copyArray(temp, game);" when strictly necessary.

Categories