python实现自动解数独小程序


Posted in Python onJanuary 21, 2019

跟朋友最近聊起来数独游戏,突发奇想使用python编写一个自动计算数独解的小程序。

数独的规则不再过多阐述,在此描述一下程序的主要思路:

(当前程序只针对于简单的数独,更复杂的还待深入挖掘)

1.计算当前每个空格可能的取值集合,并将空格顺序值对应取值集合置于字典中;

2.对取值集合位数为1,即空格处为单一取值的进行赋值,(填入动作),重复1刷新字典直到字典为空位置;

当前实现如下:

1.将数独输入列表中,并定义函数count_candinate_number(j)根据数独规则计算每一个为0的位置的当前可能取值:

#编辑数独题目,将题目输入列表中
question = [6,0,7,0,0,0,9,0,3,
  0,0,8,0,0,7,0,0,0,
  3,0,0,0,8,2,0,7,5,
  0,1,2,3,0,5,0,0,0,
  0,0,6,0,0,0,5,0,0,
  0,0,0,4,0,6,7,1,0,
  2,6,0,7,4,0,0,0,8,
  0,0,0,8,0,0,6,0,0,
  7,0,5,0,0,0,1,0,9]
 
# print(question[0])
 
#返回当前数独为0的空格中所有可能取值
def count_candidate_number(j):
 exist_all_number = [] #当前横竖大方格内所有出现的数字集
 candidate_number = [] #该方格内所有的数字候选集
 SD_Row = int(j) // 9 #行
 SD_Column = int(j) % 9 #列
 
 #用迭代器写
 exist_all_number_part1 = [question[i+SD_Row*9] for i in range(9)] #横-出现的所有数字集
 exist_all_number_part2 = [question[i*9+SD_Column] for i in range(9)] #竖-出现的所有数字集
 exist_all_number_part3 = [question[((j//9)//3)*27+((j % 9)//3)*3+i] for i in range(3)]+[question[((j//9)//3)*27+((j % 9)//3)*3+9+i] for i in range(3)]+[question[((j//9)//3)*27+((j % 9)//3)*3+18+i] for i in range(3)] #大方块-出现的所有数字集
 exist_all_number = list(set(exist_all_number_part1+exist_all_number_part2+exist_all_number_part3))  #对出现所有的数字集组合及去重
 # print(exist_all_number)
 
 #用循环写
 # for i in range(9):
 # if question[i+SD_Row*9] not in exist_all_number:
 #  exist_all_number.append(question[i+SD_Row*9])
 # if question[i*9 + SD_Cloumn] not in exist_all_number:
 #  exist_all_number.append(question[i*9 + SD_Cloumn])
 # # print(exist_all_number)
 
 #迭代器写
 candidate_number = [i for i in range(1, 10) if i not in exist_all_number] #对可能取值进行迭代输出
 
 #用循环写
 # for i in range(1,10):
 # if i not in exist_all_number:
 #  candidate_number.append(i)
 # print(candidate_number)
 
 return candidate_number

2.定义函数求解对应每个为0的位置的可能求解,并将位置信息与可能求解以键-键值的形式存储于字典中:

#对数组中每个为0的空格列出所有可能的取值数集,并放置于字典中
def all_possible_candidate_number():
 all_possible_candidate_number = {i:count_candidate_number(i) for i in range(81) if question[i] == 0}
 return all_possible_candidate_number
 # print(all_possible_candidate_number)

3.对每一个位置的可能求解进行判断,若可能解只有一个,则填入该解,循环直至数独求解完成

def main_count():
 answer_sudoku = question
 candidate_number_dic = {}
 while True:
 candidate_number_dic = all_possible_candidate_number() #在每次循环之前刷当前每个为0的空格,所有的取值集合
 if candidate_number_dic == {}:    #如果为空,则证明没有为0的空格,则为求解
  answer_sudoku = question    #对answer_sudoku赋值,并打印
  print("已求解",answer_sudoku)
  break
 else:
  for eachkey,eachValue in candidate_number_dic.items(): #对字典中位数为1的取值集合,既确定该数字变为当前应取值
  if len(eachValue) == 1:
   answer_sudoku[eachkey] = eachValue[0]
   print(eachkey,eachValue[0])   #打印对应键值及对应数值
  pass
 
if __name__ == '__main__':
 main_count()

程序运行结果:

D:\pythonwokr\venv\Scripts\python.exe D:/pythonwokr/数独.py
已求解 [6, 2, 7, 5, 1, 4, 9, 8, 3, 5, 4, 8, 9, 3, 7, 2, 6, 1, 3, 9, 1, 6, 8, 2, 4, 7, 5, 4, 1, 2, 3, 7, 5, 8, 9, 6, 9, 7, 6, 1, 2, 8, 5, 3, 4, 8, 5, 3, 4, 9, 6, 7, 1, 2, 2, 6, 9, 7, 4, 1, 3, 5, 8, 1, 3, 4, 8, 5, 9, 6, 2, 7, 7, 8, 5, 2, 6, 3, 1, 4, 9]
 
Process finished with exit code 0

程序到这里就结束了,下一步拓展是对于若不存在单独唯一解的情况,待续。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中使用logging模块打印log日志详解
Apr 05 Python
详解duck typing鸭子类型程序设计与Python的实现示例
Jun 03 Python
Python学习pygal绘制线图代码分享
Dec 09 Python
TensorFlow实现模型评估
Sep 07 Python
pandas 条件搜索返回列表的方法
Oct 30 Python
在python中获取div的文本内容并和想定结果进行对比详解
Jan 02 Python
Python实现数据结构线性链表(单链表)算法示例
May 04 Python
opencv导入头文件时报错#include的解决方法
Jul 31 Python
浅析python中while循环和for循环
Nov 19 Python
python中 _、__、__xx__()区别及使用场景
Jun 30 Python
Python 3.10 的首个 PEP 诞生,内置类型 zip() 迎来新特性(推荐)
Jul 03 Python
Jmeter调用Python脚本实现参数互相传递的实现
Jan 22 Python
python 将对象设置为可迭代的两种实现方法
Jan 21 #Python
python 实现敏感词过滤的方法
Jan 21 #Python
python执行精确的小数计算方法
Jan 21 #Python
详解安装mitmproxy以及遇到的坑和简单用法
Jan 21 #Python
python dict 相同key 合并value的实例
Jan 21 #Python
关于python之字典的嵌套,递归调用方法
Jan 21 #Python
对python 合并 累加两个dict的实例详解
Jan 21 #Python
You might like
在Mac OS上自行编译安装Apache服务器和PHP解释器
2015/12/24 PHP
用Javascript做flash做的事..才完成的一个类.Auntion Action var 0.1
2007/02/23 Javascript
childNodes.length与children.length的区别
2009/05/14 Javascript
简单的js分页脚本
2009/05/21 Javascript
jquery.alert 弹出式复选框实现代码
2009/06/15 Javascript
html+js实现动态显示本地时间
2013/09/21 Javascript
jQuery实现自动滚动到页面顶端的方法
2015/05/22 Javascript
JavaScript数组方法总结分析
2016/05/06 Javascript
js style.display=block显示布局错乱问题的解决方法
2016/09/21 Javascript
JavaScript数据结构之广义表的定义与表示方法详解
2017/04/12 Javascript
JS实现简易的图片拖拽排序实例代码
2017/06/09 Javascript
Node.JS中快速扫描端口并发现局域网内的Web服务器地址(80)
2017/09/18 Javascript
完美解决手机网页中输入框被输入法遮挡的问题
2017/12/19 Javascript
JS前端知识点offset,scroll,client,冒泡,事件对象的应用整理总结
2019/06/27 Javascript
django认证系统实现自定义权限管理的方法
2018/07/16 Python
使用matplotlib中scatter方法画散点图
2019/03/19 Python
Python实现的读取文件内容并写入其他文件操作示例
2019/04/09 Python
使用python实现抓取腾讯视频所有电影的爬虫
2019/04/15 Python
Flask模板引擎之Jinja2语法介绍
2019/06/26 Python
对python while循环和双重循环的实例详解
2019/08/23 Python
Django中密码的加密、验密、解密操作
2019/12/19 Python
对Pytorch中Tensor的各种池化操作解析
2020/01/03 Python
Python3开发实例之非关系型图数据库Neo4j安装方法及Python3连接操作Neo4j方法实例
2020/03/18 Python
pycharm无法安装第三方库的问题及解决方法以scrapy为例(图解)
2020/05/09 Python
python脚本和网页有何区别
2020/07/02 Python
用HTML5制作一个简单的弹力球游戏
2015/05/12 HTML / CSS
东南亚地区最大的购物网站Lazada新加坡站点:Lazada.sg
2016/07/17 全球购物
苹果中国官方网站:Apple中国
2016/07/22 全球购物
Michael Kors加拿大官网:购买设计师手袋、手表、鞋子、服装等
2019/03/16 全球购物
为什么会有内存对齐
2016/10/10 面试题
机械设计职业生涯规划书
2013/12/27 职场文书
医学生求职信
2014/07/01 职场文书
教师听课学习心得体会
2016/01/15 职场文书
校园文化艺术节开幕词
2016/03/04 职场文书
带你彻底理解JavaScript中的原型对象
2021/04/14 Javascript
MySQL数据管理操作示例讲解
2022/12/24 MySQL