ITPub博客

首页 > 应用开发 > Python > 编写一个程序,通过已填充的空格来解决数独问题

编写一个程序,通过已填充的空格来解决数独问题

原创 Python 作者:呼勺要b3 时间:2019-04-18 22:41:24 0 删除 编辑

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需 遵循如下规则

  1. 数字  1-9  在每一行只能出现一次。
  2. 数字  1-9  在每一列只能出现一次。
  3. 数字  1-9  在每一个以粗实线分隔的  3x3  宫内只能出现一次。

空白格用  '.'  表示。

一个数独。

答案被标成红色。

Note:

  • 给定的数独序列只包含数字  1-9  和字符  '.'  。
  • 你可以假设给定的数独只有唯一解。
  • 给定数独永远是  9x9  形式的。
def ones(board):
    #填唯一值
    e=[str(x) for x in range(1,10)]
    hhs=[[x for x in e if x not in i] for i in board]   
    lhs=[[x for x in e if x not in i] for i in [[m[n] for m in board] for n in range(9)]]   
    ghs=[[x for x in e if x not in sum(i,[])] for i in [[n[p][o-3:o] for p in range(3)] for n in [board[m-3:m] for m in [3,6,9]] for o in [3,6,9]]]    while True:
        num=0
        for i in range(9):            for j in range(9):                if board[i][j]=='.':                
                    hlghss=[x for x in hhs[i] if x in lhs[j] and x in ghs[3*(i//3)+(j//3)]]                               
                    if len(hlghss)==1:
                        num+=1
                        board[i][j]=hlghss[0]
                        hhs[i].remove(hlghss[0])
                        lhs[j].remove(hlghss[0])
                        ghs[3*(i//3)+(j//3)].remove(hlghss[0])
        if num==0:
            hlghs={}            for i in range(9):                for j in range(9):                    if board[i][j]=='.':                
                        hlghs[(i,j)]=[x for x in hhs[i] if x in lhs[j] and x in ghs[3*(i//3)+(j//3)]]
            break
    return hlghs
    #填好后返回每个格子的候选值
  
def onechoice(b,hlg):
    #依次填候选值,只填一个,填好测试唯一值,如不能填满则重置board继续填
    board=[i.copy() for i in b]    for i in hlg:        for j in hlg[i]:
            board[i[0]][i[1]]=j           
            if len(ones(board))==0:                return i[0],i[1],j
                #返回填值信息
            board=[i.copy() for i in b]
def twochoice(b,hlg):
    #选行列宫互不相等的两格,依次填值,填好测试唯一值,如不能填满则重置board继续填
    board=[i.copy() for i in b]    for i in hlg:        for j in hlg:            if i[0]!=j[0] and i[1]!=j[1] and (3*(i[0]//3)+(i[1]//3))!=(3*(j[0]//3)+(j[1]//3)):
                for m in hlg[i]:                    for n in hlg[j]:
                        board[i[0]][i[1]]=m
                        board[j[0]][j[1]]=n                        if len(ones(board))==0:                            return i[0],i[1],m,j[0],j[1],n
                            #返回填值信息
                        board=[i.copy() for i in b]
                      
one=ones(board)             
if len(one)!=0:
    oc=onechoice(board,one)    if oc!=None:
        board[oc[0]][oc[1]]=oc[2]
        ones(board)    else:
        tc=twochoice(board,one)
        board[tc[0]][tc[1]]=tc[2]
        board[tc[3]][tc[4]]=tc[5]
        ones(board)

花了一天的时间来做这道题.在递归的地方卡了很久,始终不知道该怎么写,别人的代码给了我一些灵感.感谢!

注意一点:题目中说了数独有唯一解法,所以题目中给的所有数独都可解

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31551894/viewspace-2641862/,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2019-04-17

  • 博文量
    3
  • 访问量
    1622