#!/usr/bin/perl

# Luke Perkins

# Mass Academy

# Senior 3

# January 22, 2006

# ACSL: Sudoku Solver

 

# Example:

# $ cat example.txt

# 0,5,0,0,1,0,0,4,0

# 1,0,7,0,4,0,6,0,2

# 0,0,0,9,0,5,0,0,0

# 2,0,8,6,3,0,5,9,1

# 0,4,0,0,7,0,0,2,8

# 9,0,1,0,8,0,4,0,6

# 0,0,0,4,0,1,0,0,0

# 3,0,4,0,5,8,7,0,9

# 5,2,0,0,6,0,0,1,0

# 4

# 8

# 6

# 5

# 2

# $ ./sudoku.pl < example.txt

# 278634591

# 314258769

# 931582476

# 645179328

# 197843652

 

sub solve {

    #These four variables are my'd so they don't get mixed up between recursions

    my $cannot;

    my $try;

    my $x;

    my $y;

 

    #To show the grid as it's being solved, uncomment this:

    #for($y=0;$y<9;$y++){for($x=0;$x<9;$x++){print "$grid[$y][$x]";}print "\n";}

    #Go through each row

    for ($y=0;$y<9;$y++) {

        #Go through each column

        for ($x=0;$x<9;$x++) {

            # Unless this box is filled in (not 0)

            unless ($grid[$y][$x])

            {

                # Go through each box in the same row as the current box,

                # adding all the number to the list of numbers it can't be.

                $cannot="";

                for($x2=0;$x2<9;$x2++)

                {

                    if($grid[$y][$x2]){$cannot.=$grid[$y][$x2]}

                }

                # Go through each box in the same column as the current box.

                for($y2=0;$y2<9;$y2++)

                {

                    if($grid[$y2][$x]){$cannot.=$grid[$y2][$x]}

                }

                # Go through each box in the same 3x3 box as the current box.

                $ox=int($x/3)*3;

                $oy=int($y/3)*3;

                for($x2=$ox;$x2<$ox+3;$x2++)

                {

                    for($y2=$oy;$y2<$oy+3;$y2++)

                    {

                        if($grid[$y2][$x2]){$cannot.=$grid[$y2][$x2]}

                    }

                }

                # Here it tries all the possibilities for the number at $x,$y

                # It makes sure it doesn't try a number that is in the same

                # column, row, or 3x3 box by first checking the $cannot list.

                for $try (1 .. 9)

                {

                    unless ($cannot=~m/$try/)

                    {

                        #Fill in the box with $try

                        $grid[$y][$x]=$try;

                        #Try solving it

                        solve();

                    }

                }

                #After it's done trying it can exit:

                $grid[$y][$x] = 0;

                # If it cannot be solved this way, return

                return;

            }

        }

    }

    # At this point the grid should be complete.

    # Show the five lines according to the input:

    for($n=0;$n<5;$n++)

    {

        chomp($y=<STDIN>);

        $y--;

        for($x=0;$x<9;$x++)

        {print "$grid[$y][$x]";}

        print "\n";

    }

    exit;

}

 

# Get the incomplete grid:

for($n=0;$n<9;$n++)

{

    chomp($s=<STDIN>);

    $grid[$n] = [ split(/,/, $s) ];

}

 

solve;