Created
November 1, 2012 21:10
-
-
Save Cs4r/3996566 to your computer and use it in GitHub Desktop.
Sudoku Backtracking en Perl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# | |
# bksudoku.pl | |
# | |
# Escrito por César Aguilera http://cosmobitsion.blogspot.com/ | |
# | |
# Este programa es software libre, usted puede redistribuirlo y/o | |
# modificarlo bajo los términos de la GNU General Public License | |
# publicada por la Free Software Foundation, bien de la versión 2 | |
# de la Licencia o cualquier versión posterior. | |
# | |
# Este programa se distribuye con la esperanza de que sea útil, | |
# pero SIN NINGUNA GARANTÍA, incluso sin la garantía implícita de | |
# COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Ver la | |
# GNU General Public License para más detalles. | |
# | |
# Lee de la entrada estándar o de $ARGV[0] el sudoku. | |
# El sudoku debe tener el mismo formato que la salida del script | |
# sudoku.py de David Bau | |
use strict; | |
sub imprime_sudoku{ | |
foreach my $u (0..8){ | |
print "\n" if($u%3 == 0); | |
print $u+1; | |
foreach my $v (0..8){ | |
print " " if($v%3 == 0); | |
print "|", ($_[0]->[$u][$v])?($_[0]->[$u][$v]):"_"; | |
print "|" if($v == 2 or $v == 5 or $v == 8); | |
} | |
print "\n"; | |
} | |
print "\n 1"; | |
print " ".$_ foreach (2..9); | |
print "\n"; | |
} | |
sub resuelve_sudoku{ | |
my ($tablero, $fijas, $i, $j) = @_; | |
unless($fijas->[$i][$j]){ | |
foreach (1..9){ | |
$tablero->[$i][$j] = $_; | |
if (factible($tablero, $i, $j)){ | |
if($i == 8 and $j == 8){ | |
imprime_sudoku $tablero; | |
} | |
if($i < 8 and $j == 8){ | |
resuelve_sudoku($tablero,$fijas,$i+1,0); | |
} | |
if($i <= 8 and $j < 8){ | |
resuelve_sudoku($tablero,$fijas,$i,$j+1); | |
} | |
} | |
} | |
$tablero->[$i][$j] = 0; | |
}else{ | |
if($i == 8 and $j == 8){ | |
imprime_sudoku $tablero; | |
} | |
if($i < 8 and $j == 8){ | |
resuelve_sudoku($tablero,$fijas,$i+1,0); | |
} | |
if($i <= 8 and $j < 8){ | |
resuelve_sudoku($tablero,$fijas,$i,$j+1); | |
} | |
} | |
} | |
sub factible{ | |
my ($tablero, $i, $j) = @_; | |
foreach (0..8){ | |
return 0 if(($tablero->[$_][$j] == $tablero->[$i][$j] and $i != $_) | |
or ($tablero->[$i][$_] == $tablero->[$i][$j] and $j != $_)); | |
} | |
my $fila = 3*int($i/3); | |
my $columna = 3*int($j/3); | |
foreach my $u ($fila..$fila+2){ | |
foreach my $v ($columna..$columna+2){ | |
return 0 if ($tablero->[$u][$v] == $tablero->[$i][$j] and $i != $u and $j != $v); | |
} | |
} | |
return 1; | |
} | |
my @tablero; | |
my @fijas; | |
while(<>){ | |
next if $_ !~ /\d | _/; | |
s/_/0/g; | |
push @tablero,[split /\s+/] ; | |
} | |
foreach my $u (0..8){ | |
foreach my $v(0..8){ | |
$fijas[$u][$v] = $tablero[$u][$v]?1:0; | |
} | |
} | |
resuelve_sudoku \@tablero, \@fijas, 0, 0; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment