Advertisement
lucasgautheron

Untitled

Nov 19th, 2011
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 2.86 KB | None | 0 0
  1. <?php
  2. // mem max usage by cell (bytes) : 4(1+size-1) = 4 size
  3. //  -   -    -   -  table : size*size*4size = 4size^3 bytes
  4. // size = 9 => table = 4*9^3 = 2916 bytes ~ 3 Ko : acceptable
  5. class Cell
  6. {
  7.     public $value = 0;
  8.     public $imp_values = array();
  9. }
  10.  
  11.  
  12. class Sudoku
  13. {
  14.     private $grid = array();
  15.     private $cells = array();
  16.     private $size = 0;
  17.     private $sqrtsize = 0;
  18.     private $lastsolved;
  19.    
  20.     public function cell($x, $y)
  21.     {
  22.         $i = ($y<<$this->size) + $x;
  23.         return &$this->cells[$i];
  24.     }
  25.    
  26.     private function generate_cells()
  27.     {
  28.         for($x = 0; $x < $this->size; $x++) for($y = 0; $y < $this->size; $y++)
  29.         {
  30.             $i = ($y<<$this->size) + $x;
  31.             $this->cells[$i] = new Cell();
  32.             $this->cells[$i]->value = $this->grid[$x][$y];
  33.         }
  34.     }
  35.    
  36.     // manage exclusions implied by the presence of a value
  37.     private function exclude_value($vx, $vy, $value)
  38.     {
  39.         if($value < 1 || $value > 9) return;
  40.         // line
  41.         for($x = 0; $x < $this->size; $x++)
  42.         {
  43.             $cell = $this->cell($x, $vy);
  44.             if(!in_array($value, $cell->imp_values) $cell->imp_values[] = $value;
  45.         }
  46.        
  47.         // column
  48.         for($y = 0; $y < $this->size; $y++)
  49.         {
  50.             $cell = $this->cell($vx, $y);
  51.             if(!in_array($value, $cell->imp_values) $cell->imp_values[] = $value;
  52.         }
  53.        
  54.         // big cells
  55.         $cell_x = ($vx - ($vx % $this->sqrtsize)) / $this->sqrtsize;
  56.         $cell_y = ($vy - ($vy % $this->sqrtsize)) / $this->sqrtsize;
  57.        
  58.         for($x = $cell_x; $x < $this->sqrtsize+$cell_x; $x++) for($y = $cell_y; $y < $this->sqrtsize+$cell_y; $y++)
  59.         {
  60.            $cell = $this->cell($x, $y);
  61.            if(!in_array($value, $cell->imp_values) $cell->imp_values[] = $value;
  62.         }
  63.     }
  64.    
  65.    
  66.     public function __construct($grid)
  67.     {
  68.         $this->size = sizeof($grid);
  69.         $this->sqrtsize = sqrt($this->size);
  70.         $this->grid = $grid;
  71.         $this->check();
  72.         $this->generate_cells();
  73.     }
  74.    
  75.     public function check()
  76.     {
  77.         // check grid :
  78.         for($i = 0; $i < $this->size; $i++) if(sizeof($this->grid[$i]) != $size) return false;
  79.     }
  80.    
  81.     private function cansolve()
  82.     {
  83.         $sum = 0;
  84.         for($i = 0; $i<$this->size*$this->size; $i++) $sum += $this->cells[$i];
  85.         if($sum == $this->lastsolvedsum) return false;
  86.     }
  87.    
  88.     // 1 try
  89.     private function trysolve()
  90.     {
  91.         // check impossible values and deduce solutions
  92.        
  93.         // check columns and lines !
  94.         for($x = 0; $x < $this->size; $x++) for($y = 0; $y < $this->size; $y++)
  95.         {
  96.             $cell = $this->cell($x, $y);
  97.             if($cell->value) $this->exclude_value($x, $y, $cell->value);
  98.         }
  99.        
  100.         for($i = 0; $i<$this->size*$this->size; $i++)
  101.         {
  102.             $sum = array_sum($this->cells[$i]->imp_values);
  103.             $remaining = $this->size*$this->size - $sum;
  104.             if($remaining <= $this->size)
  105.             {
  106.                 $this->cells[$i]->value = $remaining;
  107.             }
  108.         }
  109.     }
  110.    
  111.     // try to solve while we can find new values.
  112.     public function solve()
  113.     {
  114.         while($this->cansolve()) $this->trysolve();
  115.     }
  116. }
  117.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement