Sudoku solver
This is just first cut (with not much testing) and I am still working on improving it but thought it's a good time to have other brains involved
The code is in PHP, hence u'll have to run it on a LAMP/WAMP/XAMP stack to test it out.
<?php
class Sudoku {
public $cell = array();
public $small_grid = array();
public $grid = array();
public function Solve($grid){
$this->grid = $grid;
$i=0;
do{
$values_before = $this->TotalValues();
if(!$this->NormalizeCells())
break;
$this->NormalizeRows();
$this->NormalizeColumns();
$this->NormalizeSubgrid();
$values_after = $this->TotalValues();
}while($values_before != $values_after);
}
public function PrintGrid(){
for($i=0; $i<9;$i++){
for($j=0; $j<9;$j++){
echo $this->grid[$i][$j]."\t";
}
echo (($i+1)%3)? "\n" : "\n\n" ;
}
}
private function NormalizeCells(){
for($r=0; $r<9;$r++){
for($c=0; $c<9;$c++){
if($this->grid[$r][$c]!=0 && strlen($this->grid[$r][$c])==1){
continue;
}
unset($possible_values);
$possible_values = array(0,1,2,3,4,5,6,7,8,9);
for($i=0;$i<9;$i++){
if(strlen($this->grid[$r][$i])==1){
$possible_values[$this->grid[$r][$i]] = 0;
}
if(strlen($this->grid[$i][$c])==1){
$possible_values[$this->grid[$i][$c]] = 0;
}
}
$gr = ((int)($r/3))*3;
$gc = ((int)($c/3))*3;
for($i=$gr;$i<($gr+3);$i++){
for($j=$gc;$j<($gc+3);$j++){
if(strlen($this->grid[$i][$j])==1){
$possible_values[$this->grid[$i][$j]] = 0;
}
}
}
$possible_values = array_unique($possible_values);
array_shift($possible_values);
if(empty($possible_values)){
echo "<p>Wrong values entered!!!<br>";
return false;
}
$this->grid[$r][$c] = implode(',',$possible_values);
}
}
return true;
}
function NormalizeRows(){
for($r=0; $r<9;$r++){
for($c=0; $c<9;$c++){
if($this->grid[$r][$c]!=0 && strlen($this->grid[$r][$c])==1){
continue;
}
$values = explode(',', $this->grid[$r][$c]);
foreach($values as $value){
for($i=0;$i<9;$i++){
if($i==$c || empty($value))
continue;
if(strstr($this->grid[$r][$i],(string)$value))
break;
}
if($i==9)
$this->grid[$r][$c] = $value;
}
}
}
}
function NormalizeColumns(){
for($r=0; $r<9;$r++){
for($c=0; $c<9;$c++){
if($this->grid[$r][$c]!=0 && strlen($this->grid[$r][$c])==1){
continue;
}
$values = explode(',', $this->grid[$r][$c]);
foreach($values as $value){
for($i=0;$i<9;$i++){
if($i==$c || empty($value))
continue;
if(strstr($this->grid[$i][$c],(string)$value))
break;
}
if($i==9)
$this->grid[$r][$c] = $value;
}
}
}
}
function NormalizeSubgrid(){
for($r=0; $r<9;$r++){
for($c=0; $c<9;$c++){
if($this->grid[$r][$c]!=0 && strlen($this->grid[$r][$c])==1){
continue;
}
$values = explode(',', $this->grid[$r][$c]);
foreach($values as $value){
$grs = ((int)($r/3))*3;
$gre = ((int)($r/3))*3 + 3;
$gcs = ((int)($c/3))*3;
$gce = ((int)($c/3))*3 + 3;
for($gr=$grs;$gr<$gre;$gr++){
for($gc=$gcs;$gc<$gce;$gc++){
if($gr==$r && $gc==$c || empty($value))
continue;
/*if($grs==6&&gcs==0&&$r==7&&$c==1){
echo "<br>Finding $value in " . $this->grid[$gr][$gc];
}*/
if(strstr($this->grid[$gr][$gc],(string)$value))
break;
}
if($gc != $gce)
break;
}
if($gr==$gre && $gc==$gce)
$this->grid[$r][$c] = $value;
}
}
}
}
private function TotalValues(){
for($i=0; $i<9;$i++){
for($j=0; $j<9;$j++){
if($this->grid[$i][$j] == 0)
continue;
$cell_elements = strlen($this->grid[$i][$j]);
$total_elements += $cell_elements;
}
}
return $total_elements;
}
}
$grid = array( array(0,0,0, 0,0,0, 0,0,0),
array(0,0,0, 0,0,0, 0,0,0),
array(0,0,0, 0,0,0, 0,0,0),
array(0,0,0, 0,0,0, 0,0,0),
array(0,0,0, 0,0,0, 0,0,0),
array(0,0,0, 0,0,0, 0,0,0),
array(0,0,0, 0,0,0, 0,0,0),
array(0,0,0, 0,0,0, 0,0,0),
array(0,0,0, 0,0,0, 0,0,0) );
if(isset($_REQUEST['grid']) && $_REQUEST['action'] != 'Reset'){
$obj = new Sudoku;
$obj->Solve($_REQUEST['grid']);
$grid = $obj->grid;
}
for($i=0; $i<9;$i++){
unset($td);
for($j=0; $j<9;$j++){
$td .= '<td align="left" colspan="2" ><input style="width:50px" type="text" value="' . $grid[$i][$j] .'" name="' . "grid[$i][$j]" . '" /></td>'
. (($j+1)%3 ? '' : '<td> </td>');
}
$tr .= "<tr>$td</tr>" . (($i+1)%3 ? '' : '<tr><td> </td></tr>');
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<form action="sudoku.php" method="post">
<table width="50%" border="0" align="left" cellpadding="1" cellspacing="1">
<? echo $tr ?>
</table>
<input type="submit" name="action" value="Solve">
<input type="submit" name="action" value="Reset">
</form>
</html>