Reputation: 21
Just get my hand on coding and it is very addicted. So I try new challenge in making puzzle solver. I am getting so close to finish it but get stuck.
There are 2 main methods: puzzleSolver and check
I have tested check method with all cases and it is working very well.
So the only problem is solve method and I dont know whats wrong with it.
Please look at my code and help me out.
Very appreciate.
I will explain the rules below.
RULES:
1.No 3 consecutive values (1 and 2) in each row and column.
2.Each row and column contains the same amount of values.
If grid[6][6]. Each row and column will have 3 of 1s and 3 of 2s.
But cannot have 3 of 1s or 2s next each other.
Example:
grid[2][2]
0 1
1 0
Solution:
2 1
1 2
grid[2][2]
1 1
0 0
Unsolvable
It violated rule number 2.
grid[4][4]
[0, 2, 2, 1]
[0, 2, 1, 2]
[2, 1, 0, 1]
[2, 0, 0, 0]
solution:
[1, 2, 2, 1]
[1, 2, 1, 2]
[2, 1, 2, 1]
[2, 1, 1, 2]
grid[4][4]
[0, 2, 2, 2] <- violated rule number 2
[0, 2, 1, 2]
[2, 1, 0, 1]
[2, 0, 0, 0]
Unsolvable
grid[6][6]
[0, 0, 1, 1, 1, 0] <- violated rule #1
[0, 0, 0, 1, 0, 0]
[2, 2, 2, 0, 0, 0] <-violated rule #1
[0, 0, 0, 1, 0, 0]
[0, 1, 2, 0, 0, 0]
[0, 2, 0, 1, 0, 0]
Unsolvable
This is my input grid:
public static void main(String[] args) {
int[][] grid = { { 0, 1 }, { 1, 0 } };
int[][] grid1 = { { 0, 2, 2, 1 }, { 0, 2, 1, 2 }, { 2, 1, 0, 1 }, { 2, 0, 0, 0 } };
int[][] grid2 = { { 0, 2, 2, 0 }, { 0, 0, 0, 0 }, { 0, 2, 0, 0 }, { 0, 0, 0, 1 } };
int[][] grid3 = { { 0, 0, 1, 0, 2, 2 }, { 0, 0, 2, 0, 0, 0 }, { 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 2, 0, 0 },
{ 2, 0, 1, 0, 0, 0 }, { 0, 0, 2, 1, 2, 0 } };
It works in some cases but not all and I dont know why
OUTPUT
Fail to find solution
[0, 2, 2, 0]
[0, 0, 0, 0]
[0, 2, 0, 0]
[0, 0, 0, 1]
false
Solution should have:
1, 2, 2, 1
2, 1, 1, 2
1, 2, 1, 2
2, 1, 2, 1
Here is my code
Solve method will run all row and column and uses check method to decide which value to be placed
public static boolean puzzleSolve(int[][] grid) {
for (int row = 0; row < grid.length; row++) {
// column start from 0 and increasing as going down
for (int col = 0; col < grid.length; col++) {
// start at 0, 0
if (grid[row][col] == 0) { // if value =0, will be replaced with n
for (int n = 1; n < 3; n++) { // n =1 or n=2
grid[row][col] = n; // place n=1 then check condition
if (check(grid)) {
grid[row][col] = n;// if true, replace 0 with n
if (solve(grid)) { // check whole grid if violated rules
return true;
}
}
}
// System.out.println("No solution");
return false; // fail in replacing
}
}
}
// print out solved grid if succeed
System.out.println("solution: ");
for (int i = 0; i < grid.length; i++) {
System.out.println(Arrays.toString(grid[i]));
}
return true; // success
}
//end code
I have check method to detect any violations and it work well in any cases. I know there is something wrong in solve method but cannot find it.
Upvotes: 2
Views: 347
Reputation: 27956
In, pseudocode, your solution reads like:
for each cell with value zero
for each allowed value
place value in cell
check if it's a solution
Walkthrough what happens if you have all zeroes in you cells. The first cell will be given value 1, then 2, neither of which solve the whole grid (because there are still zeroes). So it moves the second cell and so on throughout the grid, leaving each cell with value 2. It obviously won't find a solution in that situation.
Your first issue here is that you actually aren't doing any recursion or backtracking.
A correct solution will likely look like:
solve (grid, position):
if position is past end and grid is solved
yah!
else
for each allowed value
place value in position on grid
call solve(grid, next position)
That's recursive (because it calls itself) and backtracking because if it can't find a solution it returns to a previous position (above it in the call stack) and tries a new value.
So an actual solution might look something like:
private void findSolutions(int[][] grid, int col, int row) {
if (row == grid.length && isSolved(grid)) {
printSolution(grid);
} else {
for (int v = 1; v <= 2; v++) {
grid[row][col] = v;
if (col == grid[row].length) {
findSolutions(grid, 0, row + 1);
} else {
findSolutions(grid, col + 1, row + 1);
}
}
}
}
Upvotes: 3