I'm trying to create a program that reads a sudoku board from a txt file and finds possible solution(s) to the board.
I've created objects of each square and added them to a 2d-array:
(This board have 28 different solutions)
001003
000000
000020
260000
000300
300102
I have successfully added the squares to corresponding column, row and box. But I'm having trouble with my recursive method that tries to find possible solution(s) of the board and add each solutions to a container in a different class that uses nodes to keep track of all the solutions. The method in my container class should take Square[][] squares as parameters.
I start the recursive method off with:
squares[0][0].fillInRemainingOfBoard();
from another class called Board.
My recursive method that is supposed to check all the squares looks like this:
protected void fillInRemainingOfBoard() {
// If Square is not '0' in the txt file it goes in here
if(this instanceof SquareDone) {
// If next != null it goes in here.
if(next != null) {
next.fillInRemainingOfBoard();
}
// If the square is empty it goes in here
} else if(this instanceof SquareEmpty) {
if(next != null) {
// Searching for possible numbers for square
// Rows, Column and Box have the same length;
//thats why row.getLength() in for-loop
for(int i=1; i<=row.getLength(); i++) {
// Set new value to square if this is true,
// then move on to next square
if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
setNewValue(i);
next.fillInRemainingOfBoard();
}
}
} else {
for(int i=1; i<=row.get(); i++) {
if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
setNewValue(i);
// No next.fillInRemainingOfBoard() here because it's the last square
}
}
}
}
}
I have a super-class for the rows, columns and boxes which holds the variables and methods for the subclasses. The method that checks for legal values looks like this:
public boolean getLegal(int square) {
for(int i=0; i<rkb.length; i++) {
if(rute == rkb[i].getVerdi()) {
return false;
}
}
return true;
}
My output of this looks like this
4 2 1 5 6 3
5 3 6 2 1 4
1 4 3 6 2 5
2 6 5 4 3 1
6 1 4 3 5 0
3 0 0 1 0 2
So my question is: Why is my code not adding values to each square and how can I save a solution and send them to another class, then start over and check for more solutions?
The reason why its not adding value to each square, is because the algorithm is incorrect. As you can see from position [5][4] of your array, value by line 2 and value by column should be 6. Meaning the algorithm messed up previous values and cannot find further ones.
I suspect this happens because in part of your code bellow, setNewValue(i) is set for the last solution found, but the if statement may find multiple solutions in the beginning of the program, as not many squares are filled, and not always the last solution is the good one.
if(next != null) {
for(int i=1; i<=row.getLength(); i++) {
if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
setNewValue(i);
next.fillInRemainingOfBoard();
}
}
To solve this, you should store all values that match the if statement and figure out how to use them later. (maybe skip the current cell if it has more then 1 solution and come back to it later)
This is just my hypothesis, but you can use a debugger to see if this is truly the problem
Here is a fast implementation of Sudoku Solver which I implemented a couple of years back.
https://gist.github.com/dapurv5/e636c85a5a85cd848ca2
You might want to read about Minimum Remaining Value heuristic. This is one of the standard ways to solve a CSP (Constraint Satisfaction Problem)
Related
I want to find a path to goal from start node using iterative depth first search using this maze represented in graph. It is a text file containing only pair of numbers like a pairwise connection a.k.a edges/arcs. Like this:
11 3
2 3
0 3
1 4
5 4
5 7
6 7
7 8
8 9
9 10
0 5
Then my code is like this:
private void performIterativeDFS(MazeGraph G, int node, int goal) {
ArrayBasedStack arrayStack = new ArrayBasedStack();
ArrayBasedStack pathStack = new ArrayBasedStack();
arrayStack.push(node);
visited[node] = true;
while (!arrayStack.isEmpty()) {
int newNode = arrayStack.pop();
if (newNode == 0) {
out.print("Starting at " + newNode + " ");
}
pathStack.push(newNode);
if (newNode == goal) {
out.println("Path if goal found: " + pathStack.toString());
}
for (int arc : G.getAdjacencyList(newNode)) {
if (!visited[arc]) {
visited[arc] = true;
arrayStack.push(arc);
}
}
}
}
I have input 0 as a starting node and goal node is 1. Then the path that output is 0,5,7,8,9,10,6,4,1. Unfortunately, that's not like a proper solution where you can go 0,5,4,1 instead. Does iterative depth first search randomly selects which nodes to go next before reaching the goal?
I tried modifying my code to do that but I can't make the path to print like 0,5,4,1. I want to keep it simple as possible so it is for everyone to understand. Any suggestions or advice?
You won't get a different answer from your search without changing your algorithm(which would not make it a dfs) or (map which would be a waste of time if you were trying to make it for anything besides this specific data set). you could try implementing a sort of backtrace after the code has found a path to reduces the number of nodes traversed, but that wouldn't be the simple answer you're looking for.
Short answer: no, that's not really how DFS works.
EDIT: missed a bit of your question, there's nothing in your code that makes it random. if, rather than
for (int arc : G.getAdjacencyList(newNode)) {
if (!visited[arc]) {
visited[arc] = true;
arrayStack.push(arc);
}
you randomly sampled G, then you would have a chance of getting the a different outcome, but as it is there is no random element to it.
I am programming a simple (or so I thought!) Checker for Sudoku puzzles using a '2D' array and an enum. The program successfully checks the grid and reports "Solution Okay!" - but it has a strange 'side effect - it prints out "invalid ROW 4" and "invalid COLUMN 1". I am new to programming and despite best efforts debugging I cannot find a solution.
(This problem was taken from CS106A Stanford University course- there are suggested solutions but I want to understand the flaw in my own code. I know it's a dirty solution and perhaps not a good example of programming. All feedback welcome.)
ROWS 1 Vaild
ROWS 2 Vaild
ROWS 3 Vaild
ROWS invalid! number: 4
ROWS 4 Vaild
ROWS 5 Vaild
ROWS 6 Vaild
ROWS 7 Vaild
ROWS 8 Vaild
ROWS 9 Vaild
All ROWS Valid
COLUMNS invalid! number: 1
COLUMNS 1 Vaild
COLUMNS 2 Vaild
COLUMNS 3 Vaild
COLUMNS 4 Vaild
COLUMNS 5 Vaild
COLUMNS 6 Vaild
COLUMNS 7 Vaild
COLUMNS 8 Vaild
COLUMNS 9 Vaild
All COLUMNS Valid
Solution Okay!
Separate file but same package
public enum Direction{
ROWS,COLUMNS,SQUARES
}
//end of enum
//import java.util.zip.Checksum;
import acm.program.ConsoleProgram;
/**
* Program that receives in a grid and checks that it is a valid sudoku solution
*
*
*/
public class SudokuTest extends ConsoleProgram {
static boolean result;
Direction direction;
public static void main(String args[]){
int[][] grid = new int[][]{
{2,5,7,9,6,4,1,8,3},
{4,9,1,8,7,3,6,5,2},
{3,8,6,1,2,5,9,4,7},
{6,4,5,7,3,2,8,1,9},
{7,1,9,5,4,8,3,2,6},
{8,3,2,6,1,9,5,7,4},
{1,6,3,2,5,7,4,9,8},
{5,7,8,4,9,6,2,3,1},
{9,2,4,3,8,1,7,6,5}
};
SudokuTest st = new SudokuTest();
result = st.checkSudokuSolution(grid);
System.out.println("The solution is correct: " + result);
}
private boolean checkSudokuSolution(int[][] grid){
//test works with line below
boolean allRowsOkay = checkElement(grid,direction.ROWS);
boolean allCOlumnsOkay = checkElement(grid,direction.COLUMNS);
if(allCOlumnsOkay&allCOlumnsOkay==true){
System.out.println("Solution Okay! ");
return true;
}
else
return false;
}
private boolean checkElement(int[][] grid,Direction direction) {
boolean []hist =new boolean[10];
int value=0; //value of the current entry
int elementCount=0;
int count=1;
int i;
int j;
//program using histogram type solution
//Check rows first - need to consider whether code can be reused for columns
for(i=0;i<=8;i++){
for(j=0;j<=8;j++){
if(direction == direction.ROWS)
{
value = grid[i][j];
}
else if(direction == direction.COLUMNS) {
value = grid[j][i];
}
else {
break;
}
hist[value] = true;
//can i reuse code for row and column?
if(hist[1]&hist[2]&hist[3]&hist[4]&hist[5]&hist[6]&hist[7]&hist[8]&hist[9]==true) {
System.out.println("" + direction +" "+(i+1) + " Vaild");
elementCount++;
hist = new boolean[10];
}
else if(hist[1]&hist[2]&hist[3]&hist[4]&hist[5]&hist[6]&hist[7]&hist[8]&hist[9]==false) {
System.out.println(direction + " invalid! " + "number: " + (i+1));
}
}
hist = new boolean[10];
}
if(elementCount==9)System.out.println("All " + direction + " Valid");
if(elementCount==9)return true;
else return false;
}
}
The statements checking the 'hits' array are very poorly formatted. the & operator is a bitwise AND. I expect you mean this to be '&&` which is logical AND. Also, in general, you don't need to compare a boolean value to true or false.
So your comparisons should read something like:
if ( hist[1] && hist[2] && ... && hist[9]) {
...
} else {
...
}
Secondly, you are running these checks 9 times per row or column (I think that's right - the indenting is mixed up so it's hard to tell). You should be running these checks outside your j for loop. In other words, it should build the hist array completely for a row or column and then check whether all 9 values are accounted for.
There are many other stylistic errors and possible logic errors but these seem to me to be the first things to fix.
Sorry, but if you can't understand your own code, it's time to re-write it. If this were my project, I'd try to divide and conquer by:
I'd fill the value array just as you're doing, within two nested for loops
But that's all I'd do inside of those loops. This will keep my code simpler and make it easier to understand and to solve the problem.
I'd analyze the value array after adding all the data to it, meaning after both nested for loops have concluded, not as you're doing it inside of the for loops.
I would create a separate method to analyze a single row/column or 9 value square
I'd have my checkElement method call these guys in a for loop.
Ok, so I have a 3 x 3 jig saw puzzle game that I am writing and I am stuck on the solution method.
public Piece[][] solve(int r, int c) {
if (isSolved())
return board;
board[r][c] = null;
for (Piece p : pieces) {
if (tryInsert(p, r, c)) {
pieces.remove(p);
break;
}
}
if (getPieceAt(r, c) != null)
return solve(nextLoc(r, c).x, nextLoc(r, c).y);
else {
pieces.add(getPieceAt(prevLoc(r, c).x, prevLoc(r, c).y));
return solve(prevLoc(r, c).x, prevLoc(r, c).y);
}
}
I know I haven't provided much info on the puzzle, but my algorithm should work regardless of the specifics. I've tested all helper methods, pieces is a List of all the unused Pieces, tryInsert attempts to insert the piece in all possible orientations, and if the piece can be inserted, it will be. Unfortunately, when I test it, I get StackOverflow Error.
Your DFS-style solution algorithm never re-adds Piece objects to the pieces variable. This is not sound, and can easily lead to infinite recursion.
Suppose, for example, that you have a simple 2-piece puzzle, a 2x1 grid, where the only valid arrangement of pieces is [2, 1]. This is what your algorithm does:
1) Put piece 1 in slot 1
2) It fits! Remove this piece, pieces now = {2}. Solve on nextLoc()
3) Now try to fit piece 2 in slot 2... doesn't work
4) Solve on prevLoc()
5) Put piece 2 in slot 1
6) It fits! Remove this piece, pieces is now empty. Solve on nextLoc()
7) No pieces to try, so we fail. Solve on prevLoc()
8) No pieces to try, so we fail. Solve on prevLoc()
9) No pieces to try, so we fail. Solve on prevLoc()
Repeat ad infinitum...
As commenters have mentioned, though, this may only be part of the issue. A lot of critical code is missing from your post, and their may be errors there as well.
I think you need to structure your recursion differently. I'm also not sure adding and removing pieces from different places of the list is safe; much as I'd rather avoid allocation in the recursion it might be safest to create a list copy, or scan the board
so far for instances of the same piece to avoid re-use.
public Piece[][] solve(int r, int c, List<Piece> piecesLeft) {
// Note that this check is equivalent to
// 'have r and c gone past the last square on the board?'
// or 'are there no pieces left?'
if (isSolved())
return board;
// Try each remaining piece in this square
for (Piece p : piecesLeft) {
// in each rotation
for(int orientation = 0; orientation < 4; ++orientation) {
if (tryInsert(p, r, c, orientation)) {
// It fits: recurse to try the next square
// Create the new list of pieces left
List<Piece> piecesLeft2 = new ArrayList<Piece>(piecesLeft);
piecesLeft2.remove(p);
// (can stop here and return success if piecesLeft2 is empty)
// Find the next point
Point next = nextLoc(r, c);
// (could also stop here if this is past end of board)
// Recurse to try next square
Piece[][] solution = solve(next.x, next.y, piecesLeft2);
if (solution != null) {
// This sequence worked - success!
return solution;
}
}
}
}
// no solution with this piece
return null;
}
StackOverflowError with recursive functions means that you're either lacking a valid recursion stop condition or you're trying to solve too big problem and should try an iterated algorithm instead. Puzzle containing 9 pieces isn't too big problem so the first thing must be the case.
The condition for ending recursion is board completion. You're only trying to insert a piece in the for loop, so the problem is probably either that the tryInsert() method doesn't insert the piece or it doesn't get invoked. As you're sure that this method works fine, I'd suggest removing break; from
if (p.equals(prev[r][c]))
{
System.out.println("Hello");
break;
}
because it's the only thing that may prevent the piece from being inserted. I'm still unsure if I understand the prev role though.
I am programming an AI for a chess-like game, based on two types of pieces on a 8 x 8 grid.
I want to build a kind of minmax tree, which represents each possible move in a game, played by white players in first, and by black players in second.
I have this generate() method which is call recursively. I need to be able to display about 8 levels of possible moves. Without optimization, this three has 8^8 leafs.
I implemented a simple system which determinate if a grid has actually ever been calculated and if its the case, system just points a child to the ever-calculated child reference.
I don't know if my explanations are clear, I will join a part of code that you should be able to understand.
The problem is that actually, I am able to generate about 3 or 4 levels of all possibilities. I am far of 8.
I would like to be able to calculate it in less than 5 seconds..
So guys, do you see a solution for optimize my algorithm ?
This is the generate function:
leftDiagonalMove(), rightDiagonalMove() and frontMove() return false if a move is illegal or move the piece in the grid and return true, if the move is legal.
clone() creates a new instance with the same properties of it's "parent" and backMove() just step back to last Move.
public void generate(Node root, boolean white, int index) {
Grid grid = root.getGrid();
Stack<Piece> whitePieces = grid.getPiecesByColor(WHITE);
Stack<Piece> blackPieces = grid.getPiecesByColor(BLACK);
Node node;
String serial = "";
// white loop
for (int i = 0; i < whitePieces.size() && white; i++) {
Piece wPiece = whitePieces.get(i);
if (grid.leftDiagonalMove(wPiece)) {
serial = grid.getSerial();
if(!allGrids.containsKey(serial)){
node = new Node(grid.clone());
node.setMove(grid.getLastMove());
root.addChild(node); // add modified grid
allGrids.put(serial, node);
//actualGrid.display();
if (index < 5 && grid.getPosition(wPiece).x > 0)
generate(node, !white, index + 1);
actualGrid.backMove(); // back step to initial grid
}
else{
root.addChild(allGrids.get(serial));
}
}
if (grid.frontMove(wPiece)) {
// same code as leftMove
}
if (grid.rightDiagonalMove(wPiece)) {
// same code as leftMove
}
}
// black loop
for (int i = 0; i < blackPieces.size() && !white; i++) {
Piece bPiece = blackPieces.get(i);
if (grid.leftDiagonalMove(bPiece)) {
// same code as white loop and replacing wPiece by bPiece
}
if (grid.frontMove(bPiece)) {
// same code as white loop and replacing wPiece by bPiece
}
if (grid.rightDiagonalMove(bPiece)) {
// same code as white loop and replacing wPiece by bPiece
}
}
}
You need to use something called AlphaBeta pruning on your generated MinMax trees of moves. More on this here:
http://en.wikipedia.org/wiki/Alpha-beta_pruning
http://www.progtools.org/games/tutorials/ai_contest/minmax_contest.pdf
Basically you do one level of branches and then using pruning you eliminate bad branches early. Then from the non eliminated branches you calculate (for each) another level. You prune again until you reach a desired depth.
Here are a few more links for you to read up on minmax:
1. http://en.wikipedia.org/wiki/Minimax
2. MinMax trees - when Min can win in two steps
This one is on optimizing pruning for chess games:
1. http://en.wikipedia.org/wiki/Alpha-beta_pruning#Heuristic_improvements
2. http://en.wikipedia.org/wiki/Refutation_table#Related_techniques
I don't understand why you are using Stacks when you are doing random access to the elements. A a low level you would get an improvement by using a Piece[] array instead.
I'm doing my homework, and am stuck on some logic (I think I used that term correctly?). I'm writing an application that shows 12 buttons numbered 1-12, 2 pictures of dice, and a Roll button.
The player rolls the dice (2, 6 sided die) and whatever number(s) he gets, he can use to "cover" some of the twelve numbers. For example, let's say he rolls the dice and gets a 3 and a 5. He gets to choose whether to cover the 3 and the 5, or the total of the two numbers - 8 (Did I mention I'm a math wiz?).
The goal of the game is to cover all the numbers using the least amount of rolls.
The problem I'm having is with, what I believe to be, the if statements:
if (die1 == 3 && die2 == 5) {
player can cover 3 and 5, or 8, but not both
}
Now, I think this works, but if I wrote all this out it would be 36 if statements (give or take zero). Is there an easier way?
By your description I think the player can select die1, die2 or die1 + die2, so to see if the user selected a valid value you need just one if.
if (cover == die1 or cover == die2 or cover == ( die1 + die2)) {
//valid..
}
no if statement needed. player can cover die1 and die2 or die1+die2
This is a good example to use a switch case, IMO.
That'd be 2 switchs which have 6 cases each.
Don't check until the player tries to cover something. By only validating the input you simplify everything down to one if statement.
If you do need to know all possibilities (maybe to show the player possible moves), then ... you still don't need all those if statements. Simply highlight the buttons that match the dice roll and only accept those as input; you'll want to index them in an array or map by their value (e.g. "1") as a way to retrieve them.
You know with two dice you always have three covering options. Presumably elsewhere in code you're going to compare your covered options with numbers. Something like
int[] covered = { die1, die2, die1+die2 };
// ... other stuff
if (comparisonValue > 6) {
// maybe do special stuff since this uses both dice
if (comparisonValue == covered[2]) {
// covered/coverable behavior
} else {
// not
}
} else {
// maybe do special stuff since this only uses one die
if (comparisonValue == covered[0] || comparisonValue == covered[1]) {
// covered/coverable behavior
} else {
// not
}
}
gives you first what's covered, then simple use of it. You could also foreach over the array to do stuff for the covered numbers, ala
for (int c : covered) {
// do stuff with c because it's covered
}
That's fairly fragile, but the flexible answer (e.g., dumping the outcomes into Collection) is way overkill for 6-sided, integer face dice, and the really flexible answer (e.g., accommodating a variable number of dice, specialized combination of faces into outcomes) is like nuclear armageddon for this particular problem.
EDIT for your particular problem, I'd do something like
// start new turn, disable all buttons
// get rolls
int[] coverable = { die1, die2, die1+die2 };
for (int covered : coverable ) {
// enabled covered button
}
If the player can change which of the 1-12 are covered by previous rolls based on a new outcome, well, then you could be in for some fun depending on how much help you want to give them.
I would probably create 2 new objects and use them with a lookup table, like so:
class TossResult{
int firstDie;
int secondDie;
}
Class Coverage{
TossResult tossResult;
int getThirdNumber(){
return tossResult.firstDie + tossResult.secondDie;
}
}
Then on application start-up, populate your map:
HashMap<TossResult, Coverage> lookup = new HashMap<>();
for (int i = 0, i < SIDES_ON_DIE; i++){
for (int j = 0, j < SIDES_ON_DIE; j++){
TossResult tempResult = new TossResult(i,j);
Coverage tempCoverage = new Coverage(tempResult);
lookup.put(tempResult, tempCoverage);
}
}
After a user rolls the dice, create a new TossResult and do a lookup.get(tossResult)
You could also create an array of 12 ints or bools. Initialize all 12 elements (say to 0 or false). Then for each role you can do something lik:
if (false == myArray[die1Value] && false == myArray[die2Value]) {
myArray[die1Value] = true;
myArray[die2Value] = true;
} else if (false == myArray[die1Value + die2Value]) {
myArray[die1Value + die2Value]
} else if (false == myArray[die1Value] || false == myArray[die2Value]) {
if (false == myArray[die1Value]) {
myArray[die1Value] = true;
}
if (false == myArray[die2Value]) {
myArray[die2Value] = true;
}
} else {
// all 12 covered
}
And certainly you can refactor this code some more.
The stated goal "The goal of the game is to cover all the numbers using the least amount of rolls." is not doable, really. The best you can do is to use probabilities to know if, for instance, you should cover on a roll of 1 and 2, a 1 and 2, or 3 first:-)