Task: Sudoku






PHP: 	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 .= PHP_EOL;
				if($i == 2 || $i == 5)
				{
					$str .=  "------+-------+------".PHP_EOL;
				}
			}
			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();



VB: Dim grid(9, 9)
Dim gridSolved(9, 9)

Public Sub Solve(i, j)
  If i > 9 Then
    
    For r = 1 To 9
      For c = 1 To 9
        gridSolved(r, c) = grid(r, c)
      Next c
    Next r
    Exit Sub
  End If
  For n = 1 To 9
    If isSafe(i, j, n) Then
      nTmp = grid(i, j)
      grid(i, j) = n
      If j = 9 Then
        Solve i + 1, 1
      Else
        Solve i, j + 1
      End If
      grid(i, j) = nTmp
    End If
  Next n
End Sub

Public Function isSafe(i, j, n) As Boolean
Dim iMin As Integer
Dim jMin As Integer

If grid(i, j) <> 0 Then
  isSafe = (grid(i, j) = n)
  Exit Function
End If



For c = 1 To 9
  If grid(i, c) = n Then
    isSafe = False
    Exit Function
  End If
Next c


For r = 1 To 9
 If grid(r, j) = n Then
   isSafe = False
   Exit Function
 End If
Next r


iMin = 1 + 3 * Int((i - 1) / 3)
jMin = 1 + 3 * Int((j - 1) / 3)
For r = iMin To iMin + 2
  For c = jMin To jMin + 2
    If grid(r, c) = n Then
      isSafe = False
      Exit Function
    End If
  Next c
Next r


isSafe = True
End Function

Public Sub Sudoku()
  
  
  

  Dim s(9) As String

  
  s(1) = "001005070"
  s(2) = "920600000"
  s(3) = "008000600"
  s(4) = "090020401"
  s(5) = "000000000"
  s(6) = "304080090"
  s(7) = "007000300"
  s(8) = "000007069"
  s(9) = "010800700"
  For i = 1 To 9
    For j = 1 To 9
      grid(i, j) = Int(Val(Mid$(s(i), j, 1)))
    Next j
  Next i
  
  Solve 1, 1
  
  Debug.Print "Solution:"
  For i = 1 To 9
    For j = 1 To 9
      Debug.Print Format$(gridSolved(i, j)); " ";
    Next j
    Debug.Print
  Next i
End Sub