CS 112 - Introduction to Computer Science II
Homework #7

Due: At the beginning of class 21.

NOTE: This work is to be done in pairs.  I strongly recommend the practice of Pair Programming described simply here.  Although team members are permitted to divide work, each team member should be able to informally present all work of his/her teammate.

To learn about Sudoku puzzles: Skim the Wikipedia article on the Sudoku puzzle.  Then solve a Sudoku puzzle online.  To work the puzzles, I recommend using software such as Sudo Cue (free PC software) or Mark Huckvale's applet.  For tips on human solution techniques, www.sudokuoftheday.com has a good techniques overview.

Of course it's easy to solve a Sudoku puzzle computationally.  There are many ways to implement a Sudoku solver, from transformation to an exact cover problem and the application of Knuth's Dancing Links algorithm (DLX), to the use of general purpose constraint programming.

As it turns out, even difficult Sudoku puzzles can be solved quickly using the simplest, brute-force techniques.  For this assignment, you will first implement a Sudoku search node, and then implement a simple iterative depth-first searcher.  In combination, these can quickly solve difficult Sudoku puzzles. 

1. Sudoku SearchNode: Implement SudokuNode according to this specification. Your implementation will extend abstract class SearchNode that we will implement together in class. Hint: Each SudokuNode should have its own private int[][] field to represent the grid.

NOTE 1: Please test your code yourself before submission. Don't use the submission system for testing. Especially don't have any extraneous printing in your submission as a search of a mind-boggling number of nodes with extraneous printing could fill up our disk with feedback files. With great power comes great responsibility. :)

NOTE 2: This is stated in the specfication but repeated here for emphasis: Your expand() method will find the first UNKNOWN cell searching each row top-to-bottom (increasing from 0), and each column left-to-right (increasing from 0) in that row.  In the example below, this is the upper-left corner cell [0][0].  The candidate values for that position are 1 and 9, so there should be two children in the list returned by expand.  Each child is created with a deep clone and is altered from the parent node by (1) having a candidate value filled in at [0][0], (2) having depth one greater than the parent node, and (3) pointing to the parent node through its parent field. Note that these latter two points are taken care of in the childClone() method.

MOST COMMON BUG: The most common SudokuNode bug experienced is that of a shallow clone of the grid rather than a necessary deep clone of the grid, causing parent and child nodes to share the same board and same changes to that board.  The easiest fix: Create a new grid (new int[SIZE][SIZE]) and copy over the parent values to the child's new grid individually in a nested for loop.  Test that a change in the child is not seen in the child's parent.

Sudoku puzzle

This grid can be used in testing in your SudokuNode grid by calling your constructors thus:

SearchNode root = new SudokuNode(new int[][] {{0,2,6,5,0,4,0,0,0},{0,8,0,0,0,9,0,0,0},{0,0,7,0,8,0,0,0,5},{0,0,0,4,0,0,0,7,0},{3,0,9,0,0,0,4,0,6},{0,6,0,0,0,3,0,0,0},{6,0,0,0,7,0,1,0,0},{0,0,0,9,0,0,0,3,0},{0,0,0,2,0,8,6,5,0}});

or

SearchNode root = new SudokuNode(new Scanner(".265.4...\n.8...9...\n..7.8...5\n...4...7.\n3.9...4.6\n.6...3...\n6...7.1..\n...9...3.\n...2.865.\n"));

or

SearchNode root = new SudokuNode(new Scanner(System.in));

with the following console (System.in) text input:

.265.4...
.8...9...
..7.8...5
...4...7.
3.9...4.6
.6...3...
6...7.1..
...9...3.
...2.865.

Suggested minimum testing: Create a root node, expand it, see that it has the correct number of children, and verify that you have not changed the root node during expansion. Remove all extra print statements in your code before submission.

2. Depth-First Search Searcher: Implement DepthFirstSearcher according to this specification. Your implementation will extend abstract class Searcher that we will implement together in class, and it would be advisable to use BreadthFirstSearcher as a starting point.  In order to test your DepthFirstSearcher, it is recommended that you first complete SudokuNode and test it with a solvable grid and an unsolvable grid within your SearchTest code developed in-class. (Depth-first search will not be able to solve your BucketsNode puzzle.  Consider why that is.)

Suggested minimum testing:  Attempt to solve both solvable and unsolvable test grids, printing the goal node when there is one.   Remove all extra print statements in your code before submission.

3. Stream Cipher: Implement StreamCipher according to this specification.  Your implementation of a cryptographically weak stream cipher will implement interface Cipher that we will implement and demonstrate together in class.  The StreamCipher object will be constructed with a long seed for a Random object. With each call to encrypt/decrypt, a Random object is created and set with this seed.  Then successive characters of the encrypted or decrypted message will be computed as the character code formed by a bitwise exclusive-or (a.k.a bitwise XOR) operation on the original character and the Random random character produced by the call nextInt(0x10000).  (16-bit character codes run from hexidecimal values 0x0000 through 0xFFFF.)  You can test the correct operation of your cipher by encrypting and decrypting a String of your choosing at first, and then confirming that you can decrypt the example below.

Here is a Java String literal that can be decrypted to a readable message using seed 42:
String secretMessage = "\uBA03\u0D9B\uAEC7\u0C36\u4F7D\uF159\u468B\uB50C\uAA15\u170E\uE763\u73E1\u5E1A\u61DA\u46F9\uB0D4\u7692\uC361\uC803\uFFFD\uEB2B\u26C6\u6FF2\u70E0\uBF98\uEE51\u6282\uCC35\u2D06\u26EF\u9806\u56BB\u359B\u400B\uD31A\u5D0F\u2C62\u28ED\u9612\u460A\uC07C\uA4EB\u9256\u14E2\u9409\u1741\uC0D1\uCC5C\u0869\u516D\u5B8F\u328D\uD13F\u0294\u6AB2\uC55F\uF968\u14D1\uB6EA\u881C\u7B4F\uDFCF\u4A8A\u381B";

Rubric: (20 points total)