求解数独

17 篇文章 0 订阅

我的代码

package main

import (
	"fmt"
)

func main() {
	//board := [][]byte{{'5', '3', '.', '.', '7', '.', '.', '.', '.'}, {'6', '.', '.', '1', '9', '5', '.', '.', '.'}, {'.', '9', '8', '.', '.', '.', '.', '6', '.'}, {'8', '.', '.', '.', '6', '.', '.', '.', '3'}, {'4', '.', '.', '8', '.', '3', '.', '.', '1'}, {'7', '.', '.', '.', '2', '.', '.', '.', '6'}, {'.', '6', '.', '.', '.', '.', '2', '8', '.'}, {'.', '.', '.', '4', '1', '9', '.', '.', '5'}, {'.', '.', '.', '.', '8', '.', '.', '7', '9'}}
	board := [][]byte{{'.', '.', '9', '7', '4', '8', '.', '.', '.'}, {'7', '.', '.', '.', '.', '.', '.', '.', '.'}, {'.', '2', '.', '1', '.', '9', '.', '.', '.'}, {'.', '.', '7', '.', '.', '.', '2', '4', '.'}, {'.', '6', '4', '.', '1', '.', '5', '9', '.'}, {'.', '9', '8', '.', '.', '.', '3', '.', '.'}, {'.', '.', '.', '8', '.', '3', '.', '2', '.'}, {'.', '.', '.', '.', '.', '.', '.', '.', '6'}, {'.', '.', '.', '2', '7', '5', '9', '.', '.'}}
	printB(board)
	solveSudoku(board)
	printB(board)

}

func printB(board [][]byte) {
	for i := 0; i < len(board); i++ {
		for j := 0; j < len(board[i]); j++ {
			fmt.Print(string(board[i][j]) + " ")
		}
		fmt.Println()
	}
	fmt.Println("***********************************")
}

type Mark struct {
	row [9]int
	col [9]int
	box [9]int
}

type Oper func(board [][]byte, row, col *int) bool

func solveSudoku(board [][]byte) {
	oper := func(board [][]byte, row, col *int) bool {
		if *row >= len(board) {
			return false
		}
		if *col < len(board[*row])-1 {
			*col++
			return true
		}
		if *row < len(board)-1 {
			*row++
			*col = 0
			return true
		}
		return false
	}
	mark := new(Mark)
	initMark(board, mark)
	solveSudokuOne(board, 0, 0, oper, mark)
}

func initMark(board [][]byte, mark *Mark) {
	for i := 0; i < len(board); i++ {
		for j := 0; j < len(board[i]); j++ {
			if board[i][j] == '.' {
				continue
			}
			n := uint(board[i][j] - '0')
			markInfo(i, j, n, mark)
		}
	}
}

//找到结果时返回结果
func solveSudokuOne(board [][]byte, row, col int, oper Oper, mark *Mark) bool {
	if board[row][col] != '.' {
		if oper(board, &row, &col) {
			return solveSudokuOne(board, row, col, oper, mark)
		}
		return true
	}
	nextValue := uint(0)
	for findNextValue(row, col, &nextValue, mark) {
		r, c := row, col
		board[r][c] = byte(nextValue) + '0'
		markInfo(row, col, nextValue, mark)
		if oper(board, &r, &c) {
			solved := solveSudokuOne(board, r, c, oper, mark)
			if solved {
				return true
			}
			remarkInfo(row, col, nextValue, mark)
		} else {
			return true
		}
	}
	board[row][col] = '.'
	return false
}

func remarkInfo(row, col int, value uint, mark *Mark) {
	markInfo(row, col, value, mark)
}

func markInfo(row, col int, value uint, mark *Mark) {
	n := 1 << (value - 1)
	mark.row[row] ^= n
	mark.col[col] ^= n
	mark.box[row/3*3+col/3] ^= n
}

//查找比nextValue大的下一个可以用的value,若存在则返回true,value存储next值
func findNextValue(row, col int, value *uint, mark *Mark) bool {
	for i := *value + 1; i < 10; i++ {
		n := 1 << (i - 1)
		if mark.row[row]^n >= mark.row[row] &&
			mark.col[col]^n >= mark.col[col] &&
			mark.box[row/3*3+col/3]^n >= mark.box[row/3*3+col/3] {
			*value = i
			return true
		}
	}
	return false
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值