看到了,季以安:用Python解数独[0],写得很详细,我没有全部看完,借用他的思路,我也来试试,回头再去看他怎么弄,特别是递归的实现方式。

先上思路:

'''1.解9*9数独的思路:(1)一个单元格的推理:根据行、列、小矩阵得出该单元格有可能填入的数值的三个列表;求并集,缩小范围,简单的题目好多单元格都能得到唯一值。(2)重复上面这个过程2.实现:(1)复制生成三个新数独(按行、按列、按小矩阵)(2)把上述三个数独每个空单元格内填满’有可能‘的数值(用列表填入)(3)遍历每个空单元格,去找这个单元格分别是三个新数独的哪个位置(是三个列表-求交集)(4)更新原数独,递归更新后的数独(5)我也知道这个程序思路,只能做比较简单的数独,就是练练,写得好会考虑怎么解高等级数独。'''图一:数独就是一个二维列表,用过xlwings操作过excel的很好理解 以下考虑算法的时候就看着这张图就行了

思路确定后,来定一下程序大致的框架:

soduku1 #待求解的数独

soduku2 #复制soduku1,然后遍历空单元格,按行来确定该单元格可能填入哪些值(一个列表),

全算出来后就是一个新数独(思路不断在二维列表和图一之间切换)

soduku3 #和上面一样,按列,基本相同,

soduku4 #按小矩阵,实现需要计算思考

A:def 复制待解数独(soduku1):

# 1.因为soduku1是有用的,不要去修改,所以复制

# 2.soduku2,soduku3的结构是一样的,所有写在一起

# 3.按行生成soduku2很简单,就是单纯的复制soduku1,只不过因为是二维列表,

要用copy.deepcopy(soduku1)才有用,不能soduku2=soduku1[:],更不能

soduku2=soduku1这么粗暴

# 4.按列生成soduku3,复杂一点,这里是框架,先不说

return newsodu

B:def 按待解数独生成小矩阵数独(soduku1):

#这个需要一点观察,还需要一点小学水平算法

return newsodu

C:def 把新生成的三个数组空格全填满(sodu):

#看图方式:cells(0,0)(看图一,这个表示第0行,第0列,即第一个

单元格,后面都采取这样的方式看图)

# soduku2的cells(0,0)会被填入[2,4,5,6],表示按行第一个单元格可能是2,4,5,6

# 全填满无非是循环

# 分别传入参数soduku2,soduku3,soduku4,就会得到三个填满的新数独

return 填满的三个新数独

def 重复算():

调用C:分别传入soduku2,soduku3,soduku4

烂尾了,本来想一步步写思路,没耐心写了,好像也不太有人看,看别人代码有时是很难受的,直接上代码,基本思路注释里还是有的。

'''1.解9*9数独的思路:(1)一个单元格的推理:根据行、列、小矩阵得出该单元格有可能填入的数值的三个列表;求并集,缩小范围,简单的题目好多单元格都能得到唯一值。(2)重复上面这个过程2.实现:(1)复制生成三个新数独(按行、按列、按小矩阵)(2)把上述三个数独每个空单元格内填满’有可能‘的数值(用列表填入)(3)遍历每个空单元格,去找这个单元格分别是三个新数独的哪个位置(是三个列表-求交集),简单的题目这一步就能得到一个唯一值(4)更新原数独,递归更新后的数独(5)我也知道这个程序思路,只能做比较简单的数独,就是练练,写得好会考虑怎么解高等级数独。'''

import copy

import numpy as np

import xlwings as xw

soduku = [[] for i in range(9)]

soduku[0] = ['',8,9,1,'',3,'','','']

soduku[1] = ['',2,7,4,'','',8,'','']

soduku[2] = ['','','',5,2,'','','','']

soduku[3] = ['',7,6,9,'','',5,'',8]

soduku[4] = [8,'',3,6,'',1,2,'','']

soduku[5] = ['',4,5,3,8,7,1,6,'']

soduku[6] = [7,'',8,2,1,4,3,9,5]

soduku[7] = [9,3,1,7,6,5,4,'',2]

soduku[8] = [4,'',2,'','',9,'','',6]

#复制待解数组

#按行直接复制

#按列用要用zip合并转换

def tran_sodu(sodu,col=None):

if col==None:

return copy.deepcopy(soduku)

else:

new_sodu=list(zip(*copy.deepcopy(soduku)))

new_sodu=[list(i) for i in new_sodu]

return new_sodu

#填满空单元格,并为了格式统一好处理,把已知的值,由数值转为列表

def input_none(sodu):

for row in sodu:

row_none = [i for i in range(1,10) if i not in row]

for x in range(len(row)):

if row[x]=="":

row[x]=row_none

else:

row[x]=[row[x]]

return sodu

'''1.按小矩阵复制待解数组,9个小矩阵组成新数独2.用了numpy知识,很好用,但在单个元素的数据类型上有很多坑3.思路:把待解数组reshape成27组,每组3个元素的矩阵A,那么第一个小矩阵就取矩阵A的第1、4、7个元素,依次类推'''

def jvzheng(soduku):

arr = np.array(soduku)

# arr=[list(i) for i in arr.reshape(27,3)]

arr = arr.reshape(27,3).tolist()

for a in arr:

for b in range(3):

if a[b]!="":

a[b]=int(a[b])

newSodu=[[] for i in range(9)]

j=0

for i in range(9):

newSodu[i]=arr[j]+arr[j+3]+arr[j+6]

j=j+1

if j>=3 and j%3==0:

j=j+6

return newSodu

'''1、开始解数独后,遍历每个空单元格,去找该单元格对应到三个新数独的单元格时:(1)如果待解数独的单元格是soduku-cells(j,k),那么对应过去,按行的当然也是:按行-cells(j,k),按列的也很简单,相反,是:按列-cells(k,j)(2)按小矩阵的难解一点,就是下面的函数,和jvzheng()的主要代码一样,就是再转置一次,就转回去了,效果是:按小矩阵-cells(j,k)(3)按行-cells(j,k),按列-cells(k,j),按小矩阵-cells(j,k)这三个列表就能求交集了,最希望得到的是一个唯一值'''

def jvzheng2(soduku):

arr = np.array(soduku)

# arr=[list(i) for i in arr.reshape(27,3)]

arr=arr.reshape(27,3).tolist()

newSodu=[[] for i in range(9)]

j=0

for i in range(9):

newSodu[i]=arr[j]+arr[j+3]+arr[j+6]

j=j+1

if j>=3 and j%3==0:

j=j+6

return newSodu

import sys

sys.setrecursionlimit(50000) #这里设置大一些

'''1.递归函数,重复2.基本原理在jvzheng2()上面写了'''

def fin(s):

global cc,rr,jz,jz2

rr=input_none(tran_sodu(soduku)) # 按行填满各空格有可能的缺失值

cc=input_none(tran_sodu(soduku,1)) #按列

jz=input_none(jvzheng(soduku)) #按小矩阵

jz2=jvzheng2(jz)

'''规则一:行、列、小矩阵求交集遍历待解数独的每个空单元格,找到该单元格在rr,cc,jz2中的位置,并求交集当这个交集只有一个值时,就填入待解数独中'''

for j in range(9):

for k in range(9):

if s[j][k]=="":

'''下面的判断是numpy数据类型的一个坑,numpy会将[9]这样的单个数值的列表直接处理成数字9,这在算到最后一步时,代码就会跳错识了,因此加了判断,核心代码是else下面的那名就够了。'''

if isinstance(jz2[j][k],int):

target=set(rr[j][k])&set(cc[k][j])

else:

target=set(rr[j][k])&set(cc[k][j])&set(jz2[j][k])

if len(target)==1:

s[j][k]=list(target)[0]

'''规则二:如[8,4,[3,7,9],6,[1,5],[1,3,5],[1,5,9],[1,3,9],2]第三个[3,7,9],虽然有三个可能值,但观察一行,‘7’,在其他位置都没有出现过,因此第三位置肯定是‘7’'''

'''规则三……规则越多,能解的难题越多,达到通用,就不会出现“递归深度不够”,”栈溢出“等问题,数独知识有限,写不下去了,只能解简单数独。'''

#每递归一次,待解数独就会更新

#把待解数独摊开,如果没有一个空值,那说明解完了

if "" not in np.array(s).reshape(1,81)[0].tolist():

# if "" not in s[3]:

return s

else:

fin(s)

return s

def main():

fin(soduku)

print(soduku)

xw.Range("K1").value = soduku

if __name__ == '__main__':

main()

解出来了,因为例子实在太简单了,稍微复杂一点就出现“栈溢出”了。

因为规则只有一条,无论怎么递归都得不到答案。

如何用python计算数独_用python解决数独相关推荐

  1. 用python计算圆周率_用python计算圆周率π

    原博文 2020-03-22 15:32 − 用python计算圆周率π 一.要求 1.要起义能计算到圆周率后面越多位越好. 2.用进度条显示计算的进度,能给出越多种进度条越好. 3.要求给出圆周率π ...

  2. 如何用python计算年龄_用Python写一个能算出自己年龄的小程序

    用Python写一个能算出自己年龄的小程序. 其实我连我今年多少岁都不知道,最近看到了python的datetime库里面有很多好用的方法,于是就写了这样一个程序作为练习,然后又写了这样一篇文章来梳理 ...

  3. python计算条件概率_用Python实现贝叶斯定理(附代码)

    写作说明 上一期我们讲了贝叶斯分类器,其中有很多的概率基础知识和贝叶斯定理.但是讲解的很没有重点,前半部分讲的是贝叶斯基础知识,最后很突兀的插进来一个文本分析-贝叶斯分类器.很多童鞋看到很累.其实上一 ...

  4. python计算圆周率_用python计算圆周率Π

    一.要求: 1.计算到圆周率后面越多位越好. 2.用进度条显示计算的进度. 3.要求给出圆周率Π的具体计算方法和解释. 二.算法: 1.拉马努金公式: 2.高斯-勒让德公式: 设置初始值: 反复执行以 ...

  5. python计算信息增益_利用Python提取ABAQUS的计算结果(ODB)信息、体积、应变等变化(一)...

    00 实例模型 一个金属长方体,我们需要对其做拉伸的加载约束示意图如图1,并在完成后采用Python命令流读取参考点的位移.体积.应变随加载时间的变化情况. 图1 金属长方体约束加载示意图 01 Py ...

  6. python计算协方差_在Python中计算协方差

    要计算协方差,您需要类似下面这样的内容,它有一个嵌套循环,遍历每个列表,并使用协方差公式累积协方差.在# let's get the mean of `X` (add all the vals in ...

  7. python计算坡度_基于python实现利用DEM数据计算坡度、坡向

    1.Python的地形三维可视化--简介Matplotlib和gdal https://blog.csdn.net/allenlu2008/article/details/51880333 2.Pyc ...

  8. python计算三角函数_使用Python三角函数公式计算三角形的夹角案例

    使用Python三角函数公式计算三角形的夹角案例 题目内容: 对于三角形,三边长分别为a, b, c,给定a和b之间的夹角C,则有:.编写程序,使得输入三角形的边a, b, c,可求得夹角C(角度值) ...

  9. python计算差商_用Python求函数的差商

    "某人"已经回答了您的问题,但您(以及未来的读者)可能会发现这些补充信息很有用.在 要获得导数的精确近似值,需要使h相当小.但是,如果将其设置得太小,那么实际上会由于Python浮 ...

  10. python计算微积分_用Python学微积分---函数

    一.什么是函数? 广义上说下面这个就叫函数,因为每当我们向机器提供豆子,这台机器便会输出豆浆. 所有输入的集合(集合的本质特点:无序重合)称为定义域(domain),其所有可能输出的集合称为值域(ra ...

最新文章

  1. Spring系列之Spring框架和SpringAOP集成过程分析(十)
  2. vue商城项目开发:axios发送请求及列表数据展示
  3. 从ca提取keystore_从keystore(jks)文件中提取私钥
  4. Linux学习笔记8
  5. connect: Address is invalid on local machine or port is not valid on remote
  6. linux 从一台服务器向另台服务器复制文件
  7. Rpc远程调用框架的设计与实现(2)
  8. 找mysql软件的配置文件_mysql 查看当前使用的配置文件my.cnf的方法
  9. spring整合quartz框架
  10. eclipse的安装与环境配置
  11. 微信搜索,不一样的搜索?
  12. android手机内存其他文件夹里,别再胡乱清理手机内存了,1秒清空这些文件夹,手机瞬间腾出50G...
  13. 4G工业路由器要点介绍
  14. Outperform
  15. 业务流程(学习笔记)
  16. 计算机硬件英语单词 m.jb51.net,计算机硬件英汉对照表
  17. 民事诉讼法知识点详细版
  18. 深圳云计算培训:关于云计算和云应用,如何入门学习?
  19. 关于DIV中display属性误区以及牵扯出来的两个问题
  20. html背景颜色中药制剂,中药制剂

热门文章

  1. VBA函数传递参数方式
  2. Matlab - 演化博弈论实现
  3. crt是什么意思 windows编程_从零开始,学习windows编程 - hello.c的疑惑!
  4. 一名高校老师的观点:高考志愿该怎么填
  5. cmos和ttl_TTL和CMOS有什么区别?
  6. access建立er图_关于ER图的快速生成 | 学步园
  7. 图解TCPIP---第二章
  8. 关于我在黑马程序员培训毕业后的亲身体验
  9. AWVS13批量脚本
  10. 分治——线性时间选择算法