<?php
// para navegador web
#define("NewLine","<br>");
// para consola/terminal
define("NewLine",PHP_EOL);
class SudokuSolver {
protected $grid = [];
protected $emptySymbol;
public static function parseString($str, $emptySymbol = '0')
{
$grid = str_split($str);
foreach($grid as &$v)
{
if($v == $emptySymbol)
{
$v = 0;
}
else
{
$v = (int)$v;
}
}
return $grid;
}
public function __construct($str, $emptySymbol = '0') {
if(strlen($str) !== 81)
{
throw new \Exception('Error sudoku');
}
$this->grid = static::parseString($str, $emptySymbol);
$this->emptySymbol = $emptySymbol;
}
public function solve()
{
try
{
$this->placeNumber(0);
return false;
}
catch(\Exception $e)
{
return true;
}
}
protected function placeNumber($pos)
{
if($pos == 81)
{
throw new \Exception('Finish');
}
if($this->grid[$pos] > 0)
{
$this->placeNumber($pos+1);
return;
}
for($n = 1; $n <= 9; $n++)
{
if($this->checkValidity($n, $pos%9, floor($pos/9)))
{
$this->grid[$pos] = $n;
$this->placeNumber($pos+1);
$this->grid[$pos] = 0;
}
}
}
protected function checkValidity($val, $x, $y)
{
for($i = 0; $i < 9; $i++)
{
if(($this->grid[$y*9+$i] == $val) || ($this->grid[$i*9+$x] == $val))
{
return false;
}
}
$startX = (int) ((int)($x/3)*3);
$startY = (int) ((int)($y/3)*3);
for($i = $startY; $i<$startY+3;$i++)
{
for($j = $startX; $j<$startX+3;$j++)
{
if($this->grid[$i*9+$j] == $val)
{
return false;
}
}
}
return true;
}
public function display() {
$str = '';
for($i = 0; $i<9; $i++)
{
for($j = 0; $j<9;$j++)
{
$str .= $this->grid[$i*9+$j];
$str .= " ";
if($j == 2 || $j == 5)
{
$str .= "| ";
}
}
$str .= NewLine;
if($i == 2 || $i == 5)
{
$str .= "------+-------+------".NewLine;
}
}
echo $str;
}
public function __toString() {
foreach ($this->grid as &$item)
{
if($item == 0)
{
$item = $this->emptySymbol;
}
}
return implode('', $this->grid);
}
}
$solver = new SudokuSolver('009170000020600001800200000200006053000051009005040080040000700006000320700003900');
$solver->solve();
$solver->display();
?>
Comentarios sobre la versión: Version 1 (1)