Ilmari Karonen wrote:
Sudoku solvers are old hat, of course, but this one is a bit different: it's a regexp. I suppose someone may have done this before, but if so, I haven't seen it. It's grossly inefficient, of course, solving the puzzle entirely by guesswork and backtracking, but that's not really the point. (It could be made quite a bit faster by hardcoding the givens in the regexp, but that would make the regexp non-generic.)

Incidentally, here's the hardcoded-givens version.  It's indeed quite a
lot faster the generic version -- I've yet to find a puzzle that would
take more than 0.1 seconds to solve on my workstation.

#!/usr/bin/perl -w
use strict;

while (defined(my $str = <>)) {
    chomp $str;
    length($str) != 81 || $str =~ tr/1-9_//c
        and (print("Bad input.\n"), next);
    $str =~ tr/_/0/;
    my $sudoku = ("^.*" .
                  (join ".*\n.*",
                   map {
                       my $n = $_;
                       ("(?!" .
                        ((join "|",
                          (map substr($str,$_,1) ||
                           ($_ < $n ? "\\" . ($_+1) : ()),
                           (grep $_ != $n &&
                            (int($_ % 9) == int($n % 9) ||
                             int($_ / 9) == int($n / 9) ||
                             int($_ / 27) == int($n / 27) &&
                             int($_ / 3 % 3) == int($n / 3 % 3)),
                            0..80))) || "x") .
                        ")(.)");
                   } 0..80) .
                  ".*\$"
                 );
    $str =~ s/(.)/$1 ? "$1\n" : "123456789\n"/eg;
    print((join("", $str =~ /$sudoku/) || "No solution."), "\n");
}

__END__

--
Ilmari Karonen

Reply via email to