Task: Sudoku





Java: public class Sudoku
{
    private int mBoard[][];
    private int mBoardSize;
    private int mBoxSize;
    private boolean mRowSubset[][];
    private boolean mColSubset[][];
    private boolean mBoxSubset[][];
 
    public Sudoku(int board[][]) {
        mBoard = board;
        mBoardSize = mBoard.length;
        mBoxSize = (int)Math.sqrt(mBoardSize);
        initSubsets();
    }
 
    public void initSubsets() {
        mRowSubset = new boolean[mBoardSize][mBoardSize];
        mColSubset = new boolean[mBoardSize][mBoardSize];
        mBoxSubset = new boolean[mBoardSize][mBoardSize];
        for(int i = 0; i < mBoard.length; i++) {
            for(int j = 0; j < mBoard.length; j++) {
                int value = mBoard[i][j];
                if(value != 0) {
                    setSubsetValue(i, j, value, true);
                }
            }
        }
    }
 
    private void setSubsetValue(int i, int j, int value, boolean present) {
        mRowSubset[i][value - 1] = present;
        mColSubset[j][value - 1] = present;
        mBoxSubset[computeBoxNo(i, j)][value - 1] = present;
    }
 
    public boolean solve() {
        return solve(0, 0);
    }
 
    public boolean solve(int i, int j) {
        if(i == mBoardSize) {
            i = 0;
            if(++j == mBoardSize) {
                return true;
            }
        }
        if(mBoard[i][j] != 0) {
            return solve(i + 1, j);
        }
        for(int value = 1; value <= mBoardSize; value++) {
            if(isValid(i, j, value)) {
                mBoard[i][j] = value;
                setSubsetValue(i, j, value, true);
                if(solve(i + 1, j)) {
                    return true;
                }
                setSubsetValue(i, j, value, false);
            }
        }
 
        mBoard[i][j] = 0;
        return false;
    }
 
    private boolean isValid(int i, int j, int val) {
        val--;
        boolean isPresent = mRowSubset[i][val] || mColSubset[j][val] || mBoxSubset[computeBoxNo(i, j)][val];
        return !isPresent;
    }
 
    private int computeBoxNo(int i, int j) {
        int boxRow = i / mBoxSize;
        int boxCol = j / mBoxSize;
        return boxRow * mBoxSize + boxCol;
    }
 
    public void print() {
        for(int i = 0; i < mBoardSize; i++) {
            if(i % mBoxSize == 0) {
                System.out.println(" -----------------------");
            }
            for(int j = 0; j < mBoardSize; j++) {
                if(j % mBoxSize == 0) {
                    System.out.print("| ");
                }
                System.out.print(mBoard[i][j] != 0 ? ((Object) (Integer.valueOf(mBoard[i][j]))) : "-");
                System.out.print(' ');
            }
 
            System.out.println("|");
        }
 
        System.out.println(" -----------------------");
    }

    public static void main(String[] args) {
        int[][] board = { 
            {8, 5, 0, 0, 0, 2, 4, 0, 0},
            {7, 2, 0, 0, 0, 0, 0, 0, 9},
            {0, 0, 4, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 7, 0, 0, 2},
            {3, 0, 5, 0, 0, 0, 9, 0, 0},
            {0, 4, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 8, 0, 0, 7, 0},
            {0, 1, 7, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 3, 6, 0, 4, 0}
        };
        Sudoku s = new Sudoku(board);
        System.out.print("Starting grid:\n");
        s.print();        
        if (s.solve()) {
            System.out.print("\nSolution:\n");
            s.print();
        } else {
            System.out.println("\nUnsolvable!");
        }
    }
}


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();