CMPSCI 187: Programming With Data Structures

David Mix Barrington

Fall, 2012

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.

Questions and answers about this project are collected here.

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:


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:

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.

Last modified 5 October 2012