37.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package main
  2. // IntMap ...
  3. type IntMap []int
  4. func (im IntMap) set(id, num int) {
  5. im[id] |= 1 << uint(num)
  6. }
  7. func (im IntMap) get(id, num int) bool {
  8. return im[id]&(1<<uint(num)) == 1
  9. }
  10. func getAnswer(occur int) (ans byte, ok bool) {
  11. cnt := 0
  12. for i, bit := 1, 1; i <= 9; i++ {
  13. if occur&bit == 0 {
  14. cnt++
  15. ans = byte(i + '0')
  16. }
  17. bit <<= 1
  18. }
  19. return ans, cnt == 1
  20. }
  21. func solveSudoku(board [][]byte) {
  22. var rowMap, colMap, blockMap IntMap
  23. rowMap = make([]int, 9)
  24. colMap = make([]int, 9)
  25. blockMap = make([]int, 9)
  26. for y, row := range board {
  27. for x, col := range row {
  28. if col == '.' {
  29. continue
  30. }
  31. num := int(col - '0')
  32. rowMap.set(y, num)
  33. colMap.set(x, num)
  34. blockMap.set(y/3*3+x/3, num)
  35. }
  36. }
  37. for y, row := range board {
  38. for x, col := range row {
  39. if col != '.' {
  40. continue
  41. }
  42. blockID := y/3*3 + x/3
  43. occur := rowMap[y] & colMap[x] & blockMap[blockID]
  44. ans, ok := getAnswer(occur)
  45. if ok {
  46. board[y][x] = ans
  47. }
  48. }
  49. }
  50. }
  51. func main() {
  52. b1 := [][]byte{
  53. {'5', '3', '.', '.', '7', '.', '.', '.', '.'},
  54. {'6', '.', '.', '1', '9', '5', '.', '.', '.'},
  55. {'.', '9', '8', '.', '.', '.', '.', '6', '.'},
  56. {'8', '.', '.', '.', '6', '.', '.', '.', '3'},
  57. {'4', '.', '.', '8', '.', '3', '.', '.', '1'},
  58. {'7', '.', '.', '.', '2', '.', '.', '.', '6'},
  59. {'.', '6', '.', '.', '.', '.', '2', '8', '.'},
  60. {'.', '.', '.', '4', '1', '9', '.', '.', '5'},
  61. {'.', '.', '.', '.', '8', '.', '.', '7', '9'}}
  62. solveSudoku(b1)
  63. printBoard(b1)
  64. }