Por la manera de abordar este problema desde una perspectiva computacional aquí sigue un programa que produzca estos sudokus en la esperanza de que el lector pueda beneficiarse de las placas que se utilizan y tal vez inventar un más compacto/algoritmo eficiente. Lo que se utiliza aquí es retroceso en su forma más básica. Hemos barrido de la junta de fila por fila, colocando compatible valores que no contradice ninguna de las restricciones (filas/columnas/cuadros). En la máquina donde se ha probado soluciones son producidos casi al instante. Para más detalles sobre el método que recomienda la upvoted trabajo por MJD en este MSE enlace. Aquí están los primeros sudokus sin progresión aritmética de longitud tres:
1 2 4 3 5 6 8 7 9
3 5 6 8 7 9 1 2 4
8 7 9 1 2 4 3 5 6
2 1 3 4 8 5 6 9 7
4 6 5 9 1 7 2 8 3
7 9 8 2 6 3 4 1 5
5 3 2 6 9 1 7 4 8
6 8 7 5 4 2 9 3 1
9 4 1 7 3 8 5 6 2
1 2 4 3 5 6 8 7 9
3 5 6 8 7 9 1 2 4
8 7 9 1 2 4 3 5 6
2 1 3 4 8 5 6 9 7
4 6 5 9 1 7 2 8 3
7 9 8 2 6 3 4 1 5
5 3 2 6 9 1 7 4 8
9 4 1 7 3 8 5 6 2
6 8 7 5 4 2 9 3 1
1 2 4 3 5 6 8 7 9
3 5 6 8 7 9 1 2 4
8 7 9 1 2 4 3 5 6
2 1 3 4 8 5 6 9 7
4 6 5 9 1 7 2 8 3
7 9 8 2 6 3 4 1 5
6 8 7 5 4 2 9 3 1
9 4 1 7 3 8 5 6 2
5 3 2 6 9 1 7 4 8
Algunas soluciones adicionales son
1 2 4 3 5 6 8 7 9
3 5 6 8 7 9 1 2 4
8 7 9 1 2 4 3 5 6
2 1 3 4 8 5 6 9 7
4 9 7 2 6 1 5 8 3
5 6 8 7 9 3 2 4 1
7 4 2 6 1 8 9 3 5
6 3 5 9 4 2 7 1 8
9 8 1 5 3 7 4 6 2
1 2 4 3 5 6 8 7 9
3 5 6 8 7 9 1 2 4
8 7 9 1 2 4 3 5 6
2 1 3 4 8 5 6 9 7
4 9 7 2 6 1 5 8 3
5 6 8 7 9 3 2 4 1
9 4 1 5 3 2 7 6 8
7 3 5 6 4 8 9 1 2
6 8 2 9 1 7 4 3 5
1 2 4 3 5 6 8 7 9
3 5 6 8 7 9 1 2 4
8 7 9 1 2 4 3 5 6
2 1 3 4 8 5 6 9 7
4 9 7 2 6 1 5 8 3
5 6 8 7 9 3 2 4 1
9 8 1 5 3 7 4 6 2
6 3 5 9 4 2 7 1 8
7 4 2 6 1 8 9 3 5
1 2 4 3 5 6 8 7 9
3 5 6 8 7 9 1 2 4
8 7 9 1 2 4 3 5 6
2 1 3 4 8 5 6 9 7
4 9 7 2 6 1 5 8 3
5 6 8 7 9 3 2 4 1
9 8 1 5 3 7 4 6 2
6 4 5 9 1 2 7 3 8
7 3 2 6 4 8 9 1 5
El código Perl para esto fue como sigue:
#! /usr/bin/perl -w
#
sub búsqueda {
my ($bordo, $regiones, $sofar) = @_;
if($sofar == 9*9){
para(mi $fila = 0; $fila < 9; $fila++){
para(mi $col = 0; $col < 9; $col++){
print "" si $col > 0;
print $tabla->[$fila][$col];
}
print "\n";
}
print "\n";
de retorno;
}
mi $col = $sofar % 9; my $fila = ($sofar-$col) / 9;
para(mi $val = 1; $val <= 9; $val++){
$tabla->[$fila][$col] = $val;
mi $admitir = 1;
foreach my $región (@$regiones){
mi %visto; mi $vacía = 0;
foreach my $ranura (@$región){
mi $ent = $tabla->[$ranura->[0]][$ranura->[1]];
if($ent == -1){
$vacía++;
}
else{
$visto{$ent} = 1;
}
}
si(escalares(teclas(%visto))+$vacía != 9){
$admitir = undef;
último;
}
}
if($row>=2){
mi @ap = (
$tabla->[$fila-2][$col],
$tabla->[$fila-1][$col],
$tabla->[$fila][$col]);
if($ap[2]-$ap[1] == $ap[1]-$ap[0]){
$admitir = undef;
}
}
if($col>=2){
mi @ap = (
$tabla->[$fila][$col-2],
$tabla->[$fila][$col-1],
$tabla->[$fila][$col]);
if($ap[2]-$ap[1] == $ap[1]-$ap[0]){
$admitir = undef;
}
}
búsqueda($bordo, $regiones, $sofar+1)
si se define($admitir);
$tabla->[$fila][$col] = -1;
}
}
PRINCIPAL: {
mi $regiones = [];
para(mi $line = 0; $line < 9; $line++){
mi $region = [
mapa {
[$linea, $_]
} (0..8) ];
push @$regiones, $región;
$region = [
mapa {
[$_, $line]
} (0..8) ];
push @$regiones, $región;
}
para(mi $fila = 0; $fila < 3; $fila++){
para(mi $col = 0; $col < 3; $col++){
mi $region = [];
para(mi $x = 0; $x < 3; $x++){
para(mi $ $ y = 0; $y < 3; $ $ y++){
push @$de la región,
[$fila*3+$x, $col*3+$y];
}
}
push @$regiones, $región;
}
}
mi $board =
[ map { [ (-1) x 9 ] } (0) x 9 ];
búsqueda($bordo, $regiones, 0);
}
Una secuencia de más en el espacio de la solución, se lee como sigue:
1 2 4 3 5 6 8 7 9
3 5 6 8 7 9 1 2 4
8 7 9 1 2 4 3 5 6
2 1 3 4 8 5 9 6 7
6 9 7 2 1 3 4 8 5
4 8 5 9 6 7 2 3 1
7 3 2 5 4 1 6 9 8
9 6 1 7 3 8 5 4 2
5 4 8 6 9 2 7 1 3
1 2 4 3 5 6 8 7 9
3 5 6 8 7 9 1 2 4
8 7 9 1 2 4 3 5 6
2 1 3 4 8 5 9 6 7
6 9 7 2 1 3 4 8 5
4 8 5 9 6 7 2 3 1
7 3 2 5 9 1 6 4 8
9 6 8 7 4 2 5 1 3
5 4 1 6 3 8 7 9 2
1 2 4 3 5 6 8 7 9
3 5 6 8 7 9 1 2 4
8 7 9 1 2 4 3 5 6
2 1 3 4 8 5 9 6 7
6 9 7 2 1 3 4 8 5
4 8 5 9 6 7 2 3 1
7 3 2 6 9 1 5 4 8
9 6 8 5 4 2 7 1 3
5 4 1 7 3 8 6 9 2
Anexo Sat Nov 15 10:40:01 CET 2014. Por la forma de responder al reto aquí es un optimizado pero simple versión de la anterior que produjo 2600 soluciones en un minuto de tiempo de cálculo, no está mal para un lenguaje interpretado y diez veces más rápido que la primera versión. Sospecho que si esto se traduce en C, el rendimiento sería muy llamativo.
#! /usr/bin/perl -w
#
sub búsqueda {
my ($bordo, $incidente, $sofar) = @_;
if($sofar == 9*9){
para(mi $fila = 0; $fila < 9; $fila++){
para(mi $col = 0; $col < 9; $col++){
print "" si $col > 0;
print $tabla->[$fila][$col];
}
print "\n";
}
print "\n";
de retorno;
}
mi $col = $sofar % 9; my $fila = ($sofar-$col) / 9;
para(mi $val = 1; $val <= 9; $val++){
mi $clave = "$fila-$col";
$tabla->[$fila][$col] = $val;
mi $admitir = 1;
foreach my $región (@{ $incidente->{$key} }){
foreach my $ranura (@$región){
if($ranura->[0] != $fila || $ranura->[1] != $col){
mi $ent = $tabla->[$ranura->[0]][$ranura->[1]];
if($ent == $val){
$admitir = undef;
último;
}
}
}
de última si no se define($admitir);
}
if($row>=2){
mi @ap = (
$tabla->[$fila-2][$col],
$tabla->[$fila-1][$col],
$tabla->[$fila][$col]);
if($ap[2]-$ap[1] == $ap[1]-$ap[0]){
$admitir = undef;
}
}
if($col>=2){
mi @ap = (
$tabla->[$fila][$col-2],
$tabla->[$fila][$col-1],
$tabla->[$fila][$col]);
if($ap[2]-$ap[1] == $ap[1]-$ap[0]){
$admitir = undef;
}
}
búsqueda($bordo, $incidente, $sofar+1)
si se define($admitir);
$tabla->[$fila][$col] = -1;
}
}
PRINCIPAL: {
mi $regiones = [];
para(mi $line = 0; $line < 9; $line++){
mi $region = [
mapa {
[$linea, $_]
} (0..8) ];
push @$regiones, $región;
$region = [
mapa {
[$_, $line]
} (0..8) ];
push @$regiones, $región;
}
para(mi $fila = 0; $fila < 3; $fila++){
para(mi $col = 0; $col < 3; $col++){
mi $region = [];
para(mi $x = 0; $x < 3; $x++){
para(mi $ $ y = 0; $y < 3; $ $ y++){
push @$de la región,
[$fila*3+$x, $col*3+$y];
}
}
push @$regiones, $región;
}
}
mi $incidente = {};
foreach my $región (@$regiones){
foreach my $ranura (@$región){
mi $clave = join('-', @$ranura);
push @{ $incidente->{$key} }, $región;
}
}
mi $board = [ map { [ (-1) x 9 ] } (0) x 9 ];
búsqueda($bordo, $incidente, 0);
}