Thursday, August 30, 2007

I've been playing around with making Kernow available through Java Web Start. This should be the ideal way to run Kernow as it places a shortcut on your desktop (and in your start menu in Windows) and auto-updates whenever a new version is available.

Reading around it seems Java Web Start has had mixed reviews. Personally I really like it, perhaps because I'm using Java 1.6 and Netbeans 6 M10 which makes it all pretty straightforward (auto jar-signing is really helpful in M10).

Wednesday, August 15, 2007

I get a lot of traffic to this blog because of my Sudoku solver. Google analytics tells me most of it lands on the original version that I wrote, and not the optimised version that's now the worlds fastest XSLT 2.0 solution - an issue which this post should hopefully rectify.

So on my machine the average execution time is 349ms, which is pretty good considering the original version would take minutes for several puzzles. As far as I know this version will solve all puzzles in under a second on my machine (Core 2 duo E6600, 2gb).

It accepts the puzzle as 81 comma separated integers in the range 0 to 9, with zero representing empty. It works by continuously reducing the number of possible values for each cell, and only when the possible values can't be reduced any further it starts backtracking.

The first phase attempts to populate as many cells of the board based on the start values. For each empty cell it works out the possible values using the "Naked Single", "Hidden Single" and "Naked Tuples" techniques in that order (read here for more on the techniques). Cells where only one possible value exists are populated and then the second phase begins.

The second phase follows this process:

* Find all empty cells and get all the possible values for each cell (using Naked Single and Hidden Single techniques) * Sort the cells by least possible values first * Populate the cells with only one possible value * If more there's more than one value, go through them one by one * Repeat

This is how it solves the Al Esgargot: A slightly modified version of the solution gives this output with the $verbose parameter set to true. As you can see it's found that it can insert a 1 at position 66 using the static analysis of the puzzle (position 66 is middle-right of the bottom-left group). Next it's decided that there are two possible values 4 and 6 at index 12 (middle-right cell of top-left group), so it tries 4 and continues. With that 4 in place it's found that there's only one possible value at index 39, a 3, so it inserts that and continues. It will keep reducing the possible values based on the current state of the board, inserting the only possible values or trying each one when there are many, until either there are no possible values for an empty cell, or the puzzle is solved.

(the solution is shown below)

Populated single value cell at index 66 with 1Trying 4 out of a possible 4 6 at index 12Only one value 3 for index 39Trying 5 out of a possible 5 7 at index 10Trying 1 out of a possible 1 9 at index 13Only one value 9 for index 15Trying 6 out of a possible 6 7 at index 16Only one value 7 for index 17Trying 2 out of a possible 2 4 at index 7Trying 6 out of a possible 6 8 at index 2Only one value 8 for index 3Only one value 2 for index 48Only one value 6 for index 57Only one value 5 for index 60Only one value 9 for index 63Only one value 5 for index 74Only one value 1 for index 78Only one value 3 for index 69Only one value 5 for index 71Only one value 6 for index 81Only one value 4 for index 36! Cannot go any further !Trying 8 out of a possible 8 at index 2Only one value 6 for index 3Trying 4 out of a possible 4 5 at index 4Only one value 3 for index 9Only one value 3 for index 23Only one value 4 for index 26Only one value 3 for index 53Only one value 5 for index 54Only one value 4 for index 36Only one value 6 for index 44Only one value 8 for index 48Only one value 2 for index 57Only one value 8 for index 73Only one value 9 for index 47Only one value 7 for index 50Only one value 6 for index 60Only one value 9 for index 64! Cannot go any further !Trying 5 out of a possible 5 at index 4Only one value 9 for index 47Only one value 2 for index 67Only one value 7 for index 49Only one value 9 for index 64Only one value 2 for index 80Only one value 1 for index 32Only one value 2 for index 48Only one value 5 for index 50Only one value 8 for index 58Only one value 8 for index 73! Cannot go any further !Trying 4 out of a possible 4 at index 7Only one value 3 for index 9Only one value 4 for index 23Only one value 3 for index 24Only one value 2 for index 26Only one value 3 for index 53Only one value 5 for index 54Only one value 8 for index 4Trying 2 out of a possible 2 6 at index 2Only one value 6 for index 3Trying 7 out of a possible 7 8 at index 19Only one value 8 for index 20Only one value 7 for index 29Only one value 9 for index 40Only one value 7 for index 50Only one value 6 for index 44Only one value 2 for index 49Only one value 2 for index 28Only one value 8 for index 48Only one value 2 for index 57Only one value 5 for index 67Only one value 7 for index 58Only one value 8 for index 61Only one value 3 for index 68Only one value 2 for index 70! Cannot go any further !Trying 8 out of a possible 8 at index 19Only one value 7 for index 20Only one value 8 for index 29Only one value 9 for index 47Only one value 2 for index 48Only one value 8 for index 57Only one value 4 for index 37Only one value 9 for index 40Only one value 7 for index 49! Cannot go any further !Trying 6 out of a possible 6 at index 2Only one value 2 for index 3Only one value 6 for index 57Trying 7 out of a possible 7 8 at index 19Only one value 8 for index 20Trying 2 out of a possible 2 4 at index 28Only one value 7 for index 29Only one value 9 for index 47Only one value 2 for index 49Only one value 9 for index 40Only one value 6 for index 44Only one value 7 for index 50Only one value 9 for index 59! Cannot go any further !Trying 4 out of a possible 4 at index 28Only one value 9 for index 37Only one value 4 for index 44Only one value 6 for index 42Trying 2 out of a possible 2 7 at index 29Only one value 7 for index 47Only one value 2 for index 49Only one value 7 for index 32Only one value 9 for index 50! Cannot go any further !Trying 7 out of a possible 7 at index 29Only one value 1 for index 32Only one value 2 for index 33Only one value 2 for index 47Trying 7 out of a possible 7 9 at index 49Only one value 9 for index 50Only one value 6 for index 77Only one value 1 for index 78Only one value 5 for index 80Only one value 5 for index 56Only one value 8 for index 60Only one value 2 for index 61Only one value 8 for index 70Only one value 6 for index 71Only one value 9 for index 74Only one value 2 for index 64Only one value 4 for index 81Only one value 4 for index 58Only one value 9 for index 67Only one value 8 for index 73Only one value 2 for index 76Done!

If you have a solution that can statically detect more cells to fill using different techniques than I have, or has a better strategy than simply backtracking when there's more than one value, then I'd be interested to know it works.

I'm pretty sure the XSLT is as good as it can be, but if you think it can be improved in any way then let me know.