# Programming Project #2: A Sudoku Solver

Originally posted 23 September 2012, due at 11:59 p.m. EDT on Saturday 6 October 2012, by placing a .java file in a subdirectoty of your cs187 directory on your edlab account, called proj2. For more information on accessing the edlab, see here or ask in discussion section.

(Deadline extended on 5 October 2012.)

Goals of this project:

1. Write a program using multiple classes written by you.
2. Write a program using stacks to implement backtrack search.

Note in green added 28 September 2012.

Note in purple added 28 September 2012.

Notes in brown added 29 September 2012.

A Latin square of order 9 is a 9 by 9 array of integers, each in the range from 1 through 9, that never has the same number occurring twice in a row or twice in a column. A sudoku is a Latin square of order 9 that also has the property that if we view the 81 cells as divided into 9 boxes, each a 3 by 3 subsquare, no number occurs twice in the same box.

A sudoku puzzle is a 9 by 9 array of integers in the range from 0 through 9, where a 0 represents a cell that must be filled in. The goal of the puzzle is to replace all the 0's with numbers in the range from 1 through 9 to form a sudoku. In commercial puzzles, care has been taken that there is exactly one sudoku that can be made by replacing the 0's. In general there might be none, or more than one. Your program will either return the first sudoku in lexicographic order, or report that there is no solution.

There are many ways to go about this problem, and we are specifying one which is quite different from the way humans solve such puzzles, but which your computer can execute very quickly. This is a backtrack search -- you will first try to find a number that can go in the first open cell without violating the sudoku property, then a number that can go in the second open cell, and so on. (The order on the cells is left to right in the top row, then left to right in the second row, and so on to the last row.) When you find that no number will go in a particular cell, you backtrack to the previous cell and try the next number there. If you run out of numbers in the first cell, there is no solutions. If you find a complete solution, you stop and report it.

Your input may come from the console as in the sample program on page 182-3 of DJW. The user will enter nine lines of text, each containing nine digits and representing a row of the puzzle. For example, the "difficult" puzzle on the New York Times website for 23 September 2012 (but see below) has the following nine rows:

400520103
090800500
100000000
800430000
000000900
056000700
000600000
030007002
020000405

Note: It is somewhat simpler to read a Board from a text file if there are spaces between the digits, becasue you can use the nextInt method in the Scanner class. So if we were to give you the puzzle above as a text file, it would look like this:

4 0 0 5 2 0 1 0 3
0 9 0 8 0 0 5 0 0
1 0 0 0 0 0 0 0 0
8 0 0 4 3 0 0 0 0
0 0 0 0 0 0 9 0 0
0 5 6 0 0 0 7 0 0
0 0 0 6 0 0 0 0 0
0 3 0 0 0 7 0 0 2
0 2 0 0 0 0 4 0 5

I miscopied the Times sudoku puzzle originally, putting two 7's in the same column. I don't know if the fixed version above is exactly what the Times had, but it does have at least one solution.

We will outline your program for you and define your two most important classes:

• A Board object is a 9 by 9 array of cells, each containing an int in the range from 0 through nine, and a 9 by 9 array of booleans telling which cells are "fixed". (These are the cells that had positive numbers in them at the start -- these numbers may not be changed.) The Board class should have a method boolean isBad( ), which tells whether the current position has a positive number occurring twice in any row, column, or box. It should have a method void move(Move m) that takes a Move object (defined below) and changes its entry accordingly. It should throw a BadMoveException if the move attempts to change a fixed cell. You may want to define additional getters and setters.

The Board class should have a constructor that takes one parameter of type String [ ]. This parameter should be an array of nine strings, each one representing a row of the puzzle. These strings should have spaces between the digits, as in the second example above.

• A Move object represents an order to change one cell of a Board. It has three int instance fields, the row and column to be changed and the new value. It has a constructor taking all three of these values and making a new Move object with them. You may want to define additional getters and setters.

• You should define a SudokuSolver class where the actual solution of the puzzle will take place. A SudokuSolver object will have a solve method that takes one parameter of type Board and returns a String. (Since any SudokuSolver object is basically the same, you need just one constructor with no parameters.)

The output string from solve will be either exactly the string "This puzzle has no solution." or nine lines of text describing the (first) completed solution. That is, there will be nine lines, separated by "\n" characters, and each line will have exactly nine digits with exactly one space between each pair of digits.

• Our driver will create a SudokuSolver object, create one or more Board objects, run the solve method on each of the Board objects, and compare the resulting strings with the correct answers. We'll make one such driver available -- we may use different example puzzles in the actual grading.

• You will have a stack of Move objects, which you may implement with either a Stack<Move> object from java.util, or with an ArrayStack<Move> or LinkedStack<Move> object from DJW's code base. Note that the names and definitions of the basic stack operations are different in these two cases.

The fundamental idea is to use the stack to record the moves that you are still considering. When you rule out a move, you pop it from the stack and undo it by setting the value of the cell it refers to 0. Then you can replace it with the move to set the same cell to the next value. If you come up with a set of moves that fills all the unfixed cells without causing a conflict, that is your solution. If you exhaust all the possibilities for the value of your first cell, there is no solution.

You should put your classes in your EdLab space, in a directory called "cs187/proj2", and test the behavior with a main method or a driver class. (We will test the code with our own driver class.)

If you create your code within Eclipse (which we encourage but don't require), you will want to ignore the warning message that says "The use of the default package is discouraged". Bear in mind that if you make the mistake of declaring the StringBag class in a package, our driver class will not see it (since it will not be in a package) and we won't be able to test your code.