|  | @@ -1,57 +1,101 @@
 | 
	
		
			
				|  |  |  package main
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// IntMap ...
 | 
	
		
			
				|  |  | -type IntMap []int
 | 
	
		
			
				|  |  | +// Slice ...
 | 
	
		
			
				|  |  | +type Slice []interface{}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (im IntMap) set(id, num int) {
 | 
	
		
			
				|  |  | -	im[id] |= 1 << uint(num)
 | 
	
		
			
				|  |  | +// Pop ...
 | 
	
		
			
				|  |  | +func (s *Slice) Pop() interface{} {
 | 
	
		
			
				|  |  | +	l := len(*s)
 | 
	
		
			
				|  |  | +	top := (*s)[l-1]
 | 
	
		
			
				|  |  | +	*s = (*s)[:l-1]
 | 
	
		
			
				|  |  | +	return top
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (im IntMap) get(id, num int) bool {
 | 
	
		
			
				|  |  | -	return im[id]&(1<<uint(num)) == 1
 | 
	
		
			
				|  |  | +// Empty ...
 | 
	
		
			
				|  |  | +func (s Slice) Empty() bool {
 | 
	
		
			
				|  |  | +	return len(s) == 0
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func getAnswer(occur int) (ans byte, ok bool) {
 | 
	
		
			
				|  |  | -	cnt := 0
 | 
	
		
			
				|  |  | -	for i, bit := 1, 1; i <= 9; i++ {
 | 
	
		
			
				|  |  | -		if occur&bit == 0 {
 | 
	
		
			
				|  |  | -			cnt++
 | 
	
		
			
				|  |  | -			ans = byte(i + '0')
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		bit <<= 1
 | 
	
		
			
				|  |  | +// Grid ...
 | 
	
		
			
				|  |  | +type Grid struct {
 | 
	
		
			
				|  |  | +	X   int
 | 
	
		
			
				|  |  | +	Y   int
 | 
	
		
			
				|  |  | +	Val int
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// SudokuMap ...
 | 
	
		
			
				|  |  | +type SudokuMap [][]int
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// NewSudokuMap ...
 | 
	
		
			
				|  |  | +func NewSudokuMap() (m SudokuMap) {
 | 
	
		
			
				|  |  | +	m = make([][]int, 3) // 0 for col, 1 for row and 2 for block id
 | 
	
		
			
				|  |  | +	for i := range m {
 | 
	
		
			
				|  |  | +		m[i] = make([]int, 9)
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	return ans, cnt == 1
 | 
	
		
			
				|  |  | +	return
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +var mask = [...]int{1, 2, 4, 8, 16, 32, 64, 128, 256, 512}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Put ...
 | 
	
		
			
				|  |  | +func (m SudokuMap) Put(x, y, val int) {
 | 
	
		
			
				|  |  | +	m[0][x] |= mask[val]
 | 
	
		
			
				|  |  | +	m[1][y] |= mask[val]
 | 
	
		
			
				|  |  | +	m[2][y/3*3+x/3] |= mask[val]
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Get ...
 | 
	
		
			
				|  |  | +func (m SudokuMap) Get(x, y, val int) bool {
 | 
	
		
			
				|  |  | +	return (m[0][x]|m[1][y]|m[2][y/3*3+x/3])&mask[val] != 0
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Del ...
 | 
	
		
			
				|  |  | +func (m SudokuMap) Del(x, y, val int) {
 | 
	
		
			
				|  |  | +	mask := mask[val] ^ 0x3FF
 | 
	
		
			
				|  |  | +	m[0][x] &= mask
 | 
	
		
			
				|  |  | +	m[1][y] &= mask
 | 
	
		
			
				|  |  | +	m[2][y/3*3+x/3] &= mask
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func solveSudoku(board [][]byte) {
 | 
	
		
			
				|  |  | -	var rowMap, colMap, blockMap IntMap
 | 
	
		
			
				|  |  | -	rowMap = make([]int, 9)
 | 
	
		
			
				|  |  | -	colMap = make([]int, 9)
 | 
	
		
			
				|  |  | -	blockMap = make([]int, 9)
 | 
	
		
			
				|  |  | -	for y, row := range board {
 | 
	
		
			
				|  |  | -		for x, col := range row {
 | 
	
		
			
				|  |  | -			if col == '.' {
 | 
	
		
			
				|  |  | -				continue
 | 
	
		
			
				|  |  | +	// Init sudoku and count blank grid
 | 
	
		
			
				|  |  | +	m := NewSudokuMap()
 | 
	
		
			
				|  |  | +	blank := 0
 | 
	
		
			
				|  |  | +	for y := range board {
 | 
	
		
			
				|  |  | +		for x := range board[y] {
 | 
	
		
			
				|  |  | +			if board[y][x] == '.' {
 | 
	
		
			
				|  |  | +				blank++
 | 
	
		
			
				|  |  | +			} else {
 | 
	
		
			
				|  |  | +				m.Put(x, y, int(board[y][x]-'0'))
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | -			num := int(col - '0')
 | 
	
		
			
				|  |  | -			rowMap.set(y, num)
 | 
	
		
			
				|  |  | -			colMap.set(x, num)
 | 
	
		
			
				|  |  | -			blockMap.set(y/3*3+x/3, num)
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	for y, row := range board {
 | 
	
		
			
				|  |  | -		for x, col := range row {
 | 
	
		
			
				|  |  | -			if col != '.' {
 | 
	
		
			
				|  |  | -				continue
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			blockID := y/3*3 + x/3
 | 
	
		
			
				|  |  | -			occur := rowMap[y] & colMap[x] & blockMap[blockID]
 | 
	
		
			
				|  |  | -			ans, ok := getAnswer(occur)
 | 
	
		
			
				|  |  | -			if ok {
 | 
	
		
			
				|  |  | -				board[y][x] = ans
 | 
	
		
			
				|  |  | +	var stack Slice = make([]interface{}, 0)
 | 
	
		
			
				|  |  | +	for len(stack) != blank { // Assume that all quetion is solvable
 | 
	
		
			
				|  |  | +		for y := 0; y < 9; y++ {
 | 
	
		
			
				|  |  | +			for x, i := 0, 1; x < 9; x++ {
 | 
	
		
			
				|  |  | +				if board[y][x] == '.' { // Never use 'copy' or 'range' when backtracking in golang!!!
 | 
	
		
			
				|  |  | +					for ; i <= 9; i++ {
 | 
	
		
			
				|  |  | +						if !m.Get(x, y, i) { // Is valid
 | 
	
		
			
				|  |  | +							m.Put(x, y, i)
 | 
	
		
			
				|  |  | +							stack = append(stack, Grid{x, y, i})
 | 
	
		
			
				|  |  | +							i = 1 // Reset next val
 | 
	
		
			
				|  |  | +							break
 | 
	
		
			
				|  |  | +						}
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +					if i == 10 { // Not valid
 | 
	
		
			
				|  |  | +						top := stack.Pop().(Grid)
 | 
	
		
			
				|  |  | +						m.Del(top.X, top.Y, top.Val)
 | 
	
		
			
				|  |  | +						x, y, i = top.X-1, top.Y, top.Val+1 // Try next val of last step
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | +	for !stack.Empty() {
 | 
	
		
			
				|  |  | +		top := stack.Pop().(Grid)
 | 
	
		
			
				|  |  | +		board[top.Y][top.X] = byte(top.Val + '0')
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func main() {
 | 
	
	
		
			
				|  | @@ -67,4 +111,18 @@ func main() {
 | 
	
		
			
				|  |  |  		{'.', '.', '.', '.', '8', '.', '.', '7', '9'}}
 | 
	
		
			
				|  |  |  	solveSudoku(b1)
 | 
	
		
			
				|  |  |  	printBoard(b1)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	println()
 | 
	
		
			
				|  |  | +	b2 := [][]byte{
 | 
	
		
			
				|  |  | +		{'.', '.', '.', '.', '.', '.', '.', '.', '.'},
 | 
	
		
			
				|  |  | +		{'.', '.', '.', '.', '.', '.', '.', '.', '.'},
 | 
	
		
			
				|  |  | +		{'.', '.', '.', '.', '.', '.', '.', '.', '.'},
 | 
	
		
			
				|  |  | +		{'.', '.', '.', '.', '.', '.', '.', '.', '.'},
 | 
	
		
			
				|  |  | +		{'.', '.', '.', '.', '.', '.', '.', '.', '.'},
 | 
	
		
			
				|  |  | +		{'.', '.', '.', '.', '.', '.', '.', '.', '.'},
 | 
	
		
			
				|  |  | +		{'.', '.', '.', '.', '.', '.', '.', '.', '.'},
 | 
	
		
			
				|  |  | +		{'.', '.', '.', '.', '.', '.', '.', '.', '.'},
 | 
	
		
			
				|  |  | +		{'.', '.', '.', '.', '.', '.', '.', '.', '.'}}
 | 
	
		
			
				|  |  | +	solveSudoku(b2)
 | 
	
		
			
				|  |  | +	printBoard(b2)
 | 
	
		
			
				|  |  |  }
 |