Python数独算法

最近突然对数独感兴趣,玩了好几天。慢慢摸索出了一些解题规律,就想着能不能用代码自动化实现。趁五一放假试着写了点代码,效果还行,至少不比网上一些教程里慢太多,因此就放到这里跟大家分享一下。

由于本人也是Python新手,很多语句可能不够简洁,还望见谅。

完整代码可见github链接:https://github.com/linking9230/sudoku.git

一、数独输入

我准备了两套数独题目作为测试,一套为困难难度的,另一套为专家难度。

困难:
在这里插入图片描述
专家:
在这里插入图片描述
我将数据放入到CSV文件中,空白格用0代替,方便读取和识别。

二、代码实现

数独的玩法大家应该都清楚,就是每一格的取值为1-9中的一个,并且在所在行,所在列,以及所在九宫格内不能重复。而游戏的难点就在于,每一个单元格,可填入的数字会有很多,这就使得我们不得不去寻找正确的数字。

当我实际在玩时,有很多小技巧,可以相对快速的找到正确的数字。但是对于编程而言,代码的优势在于计算速度快,因此使用穷举思想,也能够较快速找到正确的数字。

因此,我的第一个想法,就是利用递归循环解决问题。

——————————————————————————————————————
首先,我需要获取任意一个单元格可填入的值列表,代码如下:

def para(i):
    r=i//9
    c=i%9
    rr=r//3
    cr=c//3
    rr_d=rr*3
    rr_u=rr*3+3
    cr_d=cr*3
    cr_u=cr*3+3
    return r,c,rr_d,rr_u,cr_d,cr_u
 
def ql(m,i):
    f_l=[0,1,2,3,4,5,6,7,8,9]
    r,c,rr_d,rr_u,cr_d,cr_u=para(i)
    a=list(set(list(m[r])+list(m[:,c])+list(m[rr_d:rr_u,cr_d:cr_u].flatten())))
    q_l=[x for x in f_l if x not in a]
    return q_l,r,c

第一个函数的目的是,我在实际循环过程中,是将99的数独矩阵,展开成了811的一维列表,方便我进行循环。而利用para函数,则可以从一维列表的index返回到9*9矩阵的参数,并且获得该单元格所在九宫格的范围(rr_d,rr_u,cr_d,cr_u即为该九宫格的行列上下限)

第二个函数也很好理解,我把所在行,所在列,所在九宫格的所有值集合起来,用一个set去重,那么剩下未出现的数字,就是该单元格可以选择的值,返回为一个列表。

——————————————————————————————————————
接着,就可以递归循环解答了(后来我才知道,这种递归循环,其实也就是深度优先循环,或者DFS算法,也算歪打正着)。

def dg(m,n,i,l,flag):
	#m:matrix
	#n:flatten matrix
	#i: 第i个单元格
	#l:最后一个空单元格的位置
	
    if flag==0:
        for j in range(i,l+1):
            if n[j]==0:
                break
        q_l,r,c=ql(m,j)
        
        if 
  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值