Paratheosis' Website

You can download the Sudoku java application here.

Installation

This program is a Groovy/Java hybrid and so requires the Groovy embedded runtime library. However, getting the program running is still relatively simple. Here's how..

  1. Download the jar from the link above to your machine.
  2. Make a lib sub-directory in the same directory as the jar file.
  3. Download the most recent Groovy from here and pop the groovy-all jar file into the lib sub-directory. This jar is part of the Groovy download so you need to look through the Groovy download for the embeddable sub-directory which will contain the groovy-all-<version>.jar. For Sudoku to work you must rename this file to groovy-all.jar when you transfer it to the lib directory.
  4. Run the program using java -jar Sudoku.jar
Running

The program displays a 9x9 grid with a 'Seek Solution' button below. You can start things off by typing in the numbers for the puzzle into the appropriate places in the grid.
Once you have entered the numbers pressing the 'Seek Solution' button will send it on its merry way as it tries to solve the puzzle.
Each attempt at a solution is displayed so you can watch the solution as it progresses and the program recursively tests each possibility.
If there is a solution the program will usually arrive at it in a couple of seconds. However if a solution cannot be found, be prepared for a long wait, say for ever. if you get bored waiting you can close the app down at any time by clicking the window close icon.

The Source

Not the most concise code, and probably doesn't make use of all the Groovy code constructs that it could, but anyway here is the code for the Sudoku program.

public class Sudoku
{
    // Determines whether the value v matches all the constraints at position (i,j)
    def isCandidate( grid,i,j,v)
    {
        int x = i - i % 3
        int y = j - j % 3

        // Count how many times v appears in the 3x3 grid it is destined for.
        def total = grid.mx[x..x+2].sum
        {
             it[y..y+2].sum
             {
                 (v==it)?1:0
             }
        }

        // if already in the grid then v is not allowed
        if( total>0 ) return false

        // see if v occurs in any other place in the row
        if( null!=grid.mx[i].find{ it==v }) return false

        // see if v occurs in any other place in the column
        if( null!=grid.mx.collect{ it->it[j] }.find{it==v}) return false

        // If all constraints met then v is eligible.
        return true
    }

    def solveThread(grid)
    {
        new Thread().start
        {
            solve(grid)
        }
    }

    def solve(grid)
    {
        for(int i=0;i<grid.width;i++)
        {
            for(int j=0;j<grid.height;j++ )
            {
                if( grid.at(i,j) == 0 )
                {
                    for( int c=1;c<10;c++)
                    {
                        if( isCandidate( grid,i,j,c) )
                        {
                            grid.set(i,j,c)
                            grid.tell()
                            if( solve(grid) ) return true
                            grid.blank(i,j)
                        }
                    }                   
                    return false
                }
            }
        }
        return true;
    }       
}

Subpages (1): Programs
Comments