计算数独的脚本

总体逻辑为:从行列上去寻找非重复值,直到找到一个可选的唯一值,重复遍历找到最终的确认结果。

import math


class sudoku():
    def __init__(self, sudo_list):
        self.sudo_list = sudo_list
        self.init_range = set([x for x in range(1, 10)])

    def _init_list(self):
        self.sudo_list_bak = [[0 for x in range(9)] for y in [0 for x in range(9)]]
        for row in range(9):
            for column in range(9):
                bak_dict = {}
                bak_dict['value'] = self.sudo_list[row][column]
                block = (math.floor(row / 3) + 1, math.floor(column / 3) + 1)
                bak_dict["row"] = row
                bak_dict["column"] = column
                bak_dict["block"] = block

                self.sudo_list_bak[row][column] = bak_dict
        for row in range(9):
            for column in range(9):
                current_dict = self.sudo_list_bak[row][column]
                # print(row,column,current_dict)
                if current_dict['value'] == 0:
                    current_dict['bakvalue'] = self.init_range.copy()
                    current_dict['bakvalue'] = self._getback_value(current_dict['row'], current_dict['column'],
                                                                   current_dict['block'])

    def _getback_value(self, row, column, block):
        row_value = self._getback_row_value(row)
        column_value = self._getback_column_value(column)
        block_value = self._getback_block_value(row, column)
        return row_value.intersection(column_value, block_value)

    def _getback_row_value(self, row):
        exists_value_list = [i["value"] for i in self.sudo_list_bak[row]]
        row_value = self.init_range.copy()
        for i in exists_value_list:
            row_value.discard(i)
        return row_value

    def _getback_column_value(self, column):
        exists_value_list = [i[column]["value"] for i in self.sudo_list_bak]
        column_value = self.init_range.copy()
        for i in exists_value_list:
            column_value.discard(i)
        return column_value

    def _getback_block_value(self, row, block):
        exists_value_list = []
        for x in self.sudo_list_bak:
            for y in x:
                if y["block"] == block:
                    y['value'].append(exists_value_list)
        block_value = self.init_range.copy()
        for i in exists_value_list:
            block_value.discard(i)
        return block_value

    def compli_judge(self):
        for x in self.sudo_list_bak:
            for y in x:
                if y['value'] == 0:
                    return True
        return False

    def loop(self):
        a = 0
        while self.compli_judge():
            for x in self.sudo_list_bak:
                for y in x:
                    if y['value'] == 0 and len(y['bakvalue']) == 1:
                        y['value'] = list(y['bakvalue'])[0]
                        y.pop('bakvalue')
                        for x_new in self.sudo_list_bak:
                            for y_new in x_new:
                                if y_new['value'] == 0 and (
                                        y_new['row'] == y['row'] or y_new['column'] == y['column'] or y_new['block'] ==
                                        y[
                                            "block"]):
                                    y_new['bakvalue'].discard(y['value'])
            a += 1
            if a == 10:
                print('10次以上循环退出')
                break

    def result(self):
        self._init_list()
        self.loop()
        for x in range(9):
            for y in range(9):
                self.sudo_list[x][y] = self.sudo_list_bak[x][y]['value']
        return self.sudo_list


def result(self):
    return self.sudo_list

if __name__ == '__main__':
    sudolist = [
        [5, 0, 2, 4, 0, 0, 9, 0, 1],
        [0, 6, 0, 0, 0, 1, 2, 0, 0],
        [0, 9, 0, 0, 0, 0, 7, 8, 3],
        [0, 0, 0, 0, 8, 4, 0, 3, 9],
        [0, 0, 0, 1, 2, 7, 0, 0, 5],
        [4, 8, 0, 5, 9, 0, 6, 0, 7],
        [2, 0, 6, 0, 1, 5, 3, 9, 8],
        [0, 1, 3, 0, 0, 2, 5, 7, 0],
        [0, 0, 7, 0, 0, 0, 4, 0, 0]
    ]
    sudo = sudoku(sudolist)
    reuslt_list = sudo.result()
    for x in range(9):
        if x % 3 == 0:
            print("—" * 21)
        for y in range(9):
            if y % 3 == 0:
                print("|", end="")
            print(reuslt_list[x][y], end=" ")
        print("")
    print("—" * 21)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java实现数独计算可以使用回溯算法,以下是一个简单的实现: ```java public class SudokuSolver { private static final int SIZE = 9; // 数独大小 private static final int EMPTY = 0; // 空格子的标志 // 判断数独的某一行是否合法 private static boolean isValidRow(int[][] board, int row, int num) { for (int col = 0; col < SIZE; col++) { if (board[row][col] == num) { return false; } } return true; } // 判断数独的某一列是否合法 private static boolean isValidCol(int[][] board, int col, int num) { for (int row = 0; row < SIZE; row++) { if (board[row][col] == num) { return false; } } return true; } // 判断数独的某一宫是否合法 private static boolean isValidBox(int[][] board, int boxStartRow, int boxStartCol, int num) { for (int row = 0; row < 3; row++) { for (int col = 0; col < 3; col++) { if (board[row + boxStartRow][col + boxStartCol] == num) { return false; } } } return true; } // 判断某个位置是否可以填入指定的数字 private static boolean isValidEntry(int[][] board, int row, int col, int num) { return isValidRow(board, row, num) && isValidCol(board, col, num) && isValidBox(board, row - row % 3, col - col % 3, num); } // 使用回溯算法解决数独 public static boolean solveSudoku(int[][] board) { for (int row = 0; row < SIZE; row++) { for (int col = 0; col < SIZE; col++) { if (board[row][col] == EMPTY) { for (int num = 1; num <= SIZE; num++) { if (isValidEntry(board, row, col, num)) { board[row][col] = num; if (solveSudoku(board)) { return true; } else { board[row][col] = EMPTY; } } } return false; } } } return true; } } ``` 在上述代码中,isValidRow、isValidCol、isValidBox分别用于判断某一行、某一列、某一宫是否合法,isValidEntry用于判断某个位置是否可以填入指定的数字,solveSudoku是使用回溯算法解决数独的核心方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值