Here is a possible implementation of CheckSolution (for 3x3 only -- generalization is possible but it is left as an exercise for the reader):
sub CheckSolution
{
my $pNum = shift;
my @Sol=();
# Do some easy pair checks first.
my @digmap;
foreach my $n (@$pNum) {
my @digits = split //,$n;
foreach (0..$#digits) {
push @{$digmap[$_]->{$digits[$_]}},$n;
}
}
# Two or more with same first digit.
my $ref0 = $digmap[0];
my @lst0 = grep { scalar(@{$ref0->{$_}}) > 1 } keys %$ref0;
return @Sol if (! scalar(@lst0));
# Two or more with same middle digit.
my $ref1 = $digmap[1];
my @lst1 = grep { scalar(@{$ref1->{$_}}) > 1 } keys %$ref1;
return @Sol if (! scalar(@lst1));
# Two or more with same last digit
my $ref2 = $digmap[2];
my @lst2 = grep { scalar(@{$ref2->{$_}}) > 1 } keys %$ref2;
return @Sol if (! scalar(@lst2));
#print "Passed pair test\n";
# Use these lists for candidates for the three row positions.
my @uppers = map { @{$ref0->{$_}} } @lst0;
my @centers = map { @{$ref1->{$_}} } @lst1;
my @bottoms = map { @{$ref2->{$_}} } @lst2;
my ($upper, $center, $bottom);
my ($a, $b, $c, $d, $e, $f, $g, $h, $i);
my ($adg, $beh, $cfi);
# hash to simplify checking for duplicates.
my %wholeset = map { $_ => 1 } @$pNum;
my (%t1, %t2, %t3);
foreach $upper (@uppers) {
%t1 = %wholeset;
$t1{$upper} = 0;
foreach $center (@centers) {
next if (! $t1{$center});
%t2 = %t1;
$t2{$center} = 0;
foreach $bottom (@bottoms) {
next if (! $t2{$bottom});
%t3 = %t2;
$t3{$bottom} = 0;
($a, $b, $c) = split //,$upper;
($d, $e, $f) = split //,$center;
($g, $h, $i) = split //,$bottom;
$adg = $a . $d . $g;
next if (! $t3{$adg});
$t3{$adg} = 0;
$beh = $b . $e . $h;
next if (! $t3{$beh});
$t3{$beh} = 0;
$cfi = $c . $f . $i;
next if (! $t3{$cfi});
# Solution found - return it.
return ($upper, $center, $bottom);
} # bottom
} # center
} #upper
return @Sol;
}
I tried this and it found the 132-792-660 (divisor 44) case in about 4 seconds.