soduku 数独(逻辑游戏)

soduku 数独(逻辑游戏)

数独(shù dú)是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9 。

数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。

  • 起源
    既然“数独”有一个字是“数”,人们也往往会联想到数学,那就不妨从大家都知道的数学家欧拉说起,但凡想了解数独历史的玩家在网络、书籍中搜索时,共同会提到的就是欧拉的“拉丁方块(Latin square)”。

    拉丁方块的规则:每一行(Row)、每一列(Column)均含1-N(N即盘面的规格),不重复。这与前面提到的标准数独非常相似,但少了一个宫的规则。

  • 近代发展
    数独起源于18世纪初瑞士数学家欧拉等人研究的拉丁方阵(Latin Square)。19世纪80年代,一位美国的退休建筑师格昂斯(Howard Garns)根据这种拉丁方阵发明了一种填数趣味游戏,这就是数独的雏形。20世纪70年代,人们在美国纽约的一本益智杂志《Math Puzzles and Logic Problems》上发现了这个游戏,当时被称为填数字(Number Place),这也是公认的数独最早的见报版本。1984年一位日本学者将其介绍到了日本,发表在Nikoli公司的一本游戏杂志上,当时起名为“数字は独身に限る”(すうじはどくしんにかぎる),就改名为“数独”(すうどく),其中“数”(すう)是数字的意思,“独”(どく)是唯一的意思。后来一位前任香港高等法院的新西兰籍法官高乐德(Wayne Gould)在1997年3月到日本东京旅游时,无意中发现了。他首先在英国的《泰晤士报》上发表,不久其他报纸也发表,很快便风靡全英国,之后他用了6年时间编写了电脑程序,并将它放在网站上(这个网站也就是著名的数独玩家论坛),后来因一些原因,网站被关闭,幸好数独大师Glenn Fowler恢复了数据,玩家论坛有了新处所。在90年代国内就有部分的益智类书籍开始刊登,南海出版社在2005年出版了《数独1-2》,随后日本著名数独制题人西尾彻也的《数独挑战》也由辽宁教育出版社出版。《北京晚报》、《扬子晚报》、《羊城晚报》、《新民晚报》、《成都商报》等等报纸媒体也先后刊登了数独游戏。

  • 组成元素

    • 方格
      水平方向有九横行,垂直方向有九纵列的矩形,画分八十一个小正方形,称为九宫格(Grid),如图一所示,是数独(Sudoku)的作用范围。

    • 水平方向的每一横行有九格,每一横行称为行(Row)

    • 垂直方向的每一纵列有九格,每一纵列称为列(Column)

    • 三行与三列相交之处有九格,每一单元称为小九宫(Box、Block),简称宫,如图四所示(在杀手数独中,宫往往用单词Nonet表示)。
    • 组成
      上述行、列、宫、单元格统称为单元(Unit);而行、列、宫统称为区域(Region)。
    • 区块
      由三个连续宫组成大行列(Chute),分大行(Floor)及大列(Tower)。
      第一大行:由第一宫、第二宫、第三宫组成。
      第二大行:由第四宫、第五宫、第六宫组成。
      第三大行:由第七宫、第八宫、第九宫组成。
      第一大列:由第一宫、第四宫、第七宫组成。
      第二大列:由第二宫、第五宫、第八宫组成。
      第三大列:由第三宫、第六宫、第九宫组成。
    • 格位编号
      格位按所处的行列单元赋予坐标值
      坐标有多种标示法,有横行 A~I,纵列 1~9(如中国),也有横行 1~9,纵列 AI(如日本),这两种标示容易混淆,故最被广泛使用的是横行R1R9,纵列C1~C9的标示法。
  • 提示数
    在九宫格的格位填上一些数字,做为填数判断的线索(Hint),称为提示数(Clue)

  • 解题手法
    依解题填制的过程可区分为直观法与候选数法。

    直观法就是不做任何记号,直接从数独的盘势观察线索,推论答案的方法。

    候选数法就是删减等位群格位已出现的数字,将剩余可填数字填入空格做为解题线索的参考,可填数字称为候选数(Candidates,或称备选数)。

    直观法和候选数法只是填制时候是否有注记的区别,依照个人习惯而定,并非鉴定题目难度或技巧难度的标准,无论是难题或是简单题都可上述方法填制,一般程序解题以候选数法较多。

  • 基础解法

    • 排除法(摒除法)
      摒除法:用数字去找单元内唯一可填空格,称为摒除法,数字可填唯一空格称为排除法 (Hidden Single)。
      根据不同的作用范围,摒余解可分为下述三种:
      数字可填唯一空格在「宫」单元称为宫排除(Hidden Single in Box),也称宫摒除法。
      数字可填唯一空格在「行」单元称为行排除法(Hidden Single in Row),也称行摒除法。
      数字可填唯一空格在「列」单元称为列排除法(Hidden Single in Column),也称列摒除法。
    • 唯一余数法
      唯一余数法:用格位去找唯一可填数字,称为余数法,格位唯一可填数字称为唯余解(Naked Single)。
      余数法是删减等位群格位(Peer)已出现的数字的方法,每一格位的等位群格位有 20 个

代码

[soduku.py]{..\src\backtracking\soduku.py}

"""
Prepare
   1. sys.path 中增加 TheAlgorithms\src 子模块

"""
import sys
sys.path.append('E:\dev\AI\TheAlgorithms\src')

案例一:

def sudoku(grid: Matrix) 
-> Optional[Matrix]:
    """
    Takes a partially filled-in grid and attempts to assign values to
    all unassigned locations in such a way to meet the requirements
    for Sudoku solution (non-duplication across rows, columns, and boxes)
from backtracking.sudoku import Matrix,sudoku,print_solution
"""
"""
# assigning initial values to the grid
initial_grid: Matrix = [
    [3, 0, 6, 5, 0, 8, 4, 0, 0],
    [5, 2, 0, 0, 0, 0, 0, 0, 0],
    [0, 8, 7, 0, 0, 0, 0, 3, 1],
    [0, 0, 3, 0, 1, 0, 0, 8, 0],
    [9, 0, 0, 8, 6, 3, 0, 0, 5],
    [0, 5, 0, 0, 9, 0, 6, 0, 0],
    [1, 3, 0, 0, 0, 0, 2, 5, 0],
    [0, 0, 0, 0, 0, 0, 0, 7, 4],
    [0, 0, 5, 2, 0, 6, 3, 0, 0],
]

# a grid with no solution
no_solution: Matrix = [
    [5, 0, 6, 5, 0, 8, 4, 0, 3],
    [5, 2, 0, 0, 0, 0, 0, 0, 2],
    [1, 8, 7, 0, 0, 0, 0, 3, 1],
    [0, 0, 3, 0, 1, 0, 0, 8, 0],
    [9, 0, 0, 8, 6, 3, 0, 0, 5],
    [0, 5, 0, 0, 9, 0, 6, 0, 0],
    [1, 3, 0, 0, 0, 0, 2, 5, 0],
    [0, 0, 0, 0, 0, 0, 0, 7, 4],
    [0, 0, 5, 2, 0, 6, 3, 0, 0],
]

for example_grid in (initial_grid, no_solution):
        print("\nExample grid:\n" + "=" * 20)
        print_solution(example_grid)
        print("\nExample grid solution:")
        solution = sudoku(example_grid)
        if solution is not None:
            print_solution(solution)
        else:
            print("Cannot find a solution.")

Example grid:
====================
3 0 6 5 0 8 4 0 0 
5 2 0 0 0 0 0 0 0 
0 8 7 0 0 0 0 3 1 
0 0 3 0 1 0 0 8 0 
9 0 0 8 6 3 0 0 5 
0 5 0 0 9 0 6 0 0 
1 3 0 0 0 0 2 5 0 
0 0 0 0 0 0 0 7 4 
0 0 5 2 0 6 3 0 0 

Example grid solution:
3 1 6 5 7 8 4 9 2 
5 2 9 1 3 4 7 6 8 
4 8 7 6 2 9 5 3 1 
2 6 3 4 1 5 9 8 7 
9 7 4 8 6 3 1 2 5 
8 5 1 7 9 2 6 4 3 
1 3 8 9 4 7 2 5 6 
6 9 2 3 5 1 8 7 4 
7 4 5 2 8 6 3 1 9 

Example grid:
====================
5 0 6 5 0 8 4 0 3 
5 2 0 0 0 0 0 0 2 
1 8 7 0 0 0 0 3 1 
0 0 3 0 1 0 0 8 0 
9 0 0 8 6 3 0 0 5 
0 5 0 0 9 0 6 0 0 
1 3 0 0 0 0 2 5 0 
0 0 0 0 0 0 0 7 4 
0 0 5 2 0 6 3 0 0 

Example grid solution:
Cannot find a solution.
posted @ 2021-06-16 14:11  IT88老兵  阅读(786)  评论(0编辑  收藏  举报