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中解析XML数据的方法
Oct 15 Python
python实现微信发送邮件关闭电脑功能
Feb 22 Python
Python获取二维矩阵每列最大值的方法
Apr 03 Python
python实现决策树分类
Aug 30 Python
在PyCharm导航区中打开多个Project的关闭方法
Jan 17 Python
Python 数据库操作 SQLAlchemy的示例代码
Feb 18 Python
Django Sitemap 站点地图的实现方法
Apr 29 Python
Python生命游戏实现原理及过程解析(附源代码)
Aug 01 Python
python Plotly绘图工具的简单使用
Mar 03 Python
python实现飞机大战项目
Mar 11 Python
Python数据分析库pandas高级接口dt的使用详解
Dec 11 Python
Python上下文管理器Content Manager
Jun 26 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
PHP的Yii框架中移除组件所绑定的行为的方法
2016/03/18 PHP
js自动闭合html标签(自动补全html标记)
2012/10/04 Javascript
javascript页面加载完执行事件代码
2014/02/11 Javascript
jQuery使用prepend()方法在元素前添加内容用法实例
2015/03/26 Javascript
jquery带下拉菜单和焦点图代码分享
2015/08/24 Javascript
JS实现状态栏跑马灯文字效果代码
2015/10/24 Javascript
JavaScript在网页中画圆的函数arc使用方法
2015/11/13 Javascript
JavaScript中的函数(二)
2015/12/23 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
基于Bootstrap漂亮简洁的CSS3价格表(附源码下载)
2017/02/28 Javascript
JavaScript中transform实现数字翻页效果
2017/03/08 Javascript
jQuery实现文章图片弹出放大效果
2017/04/06 jQuery
Vue实现一个返回顶部backToTop组件
2017/07/25 Javascript
windows下更新npm和node的方法
2017/11/30 Javascript
详解webpack 入门与解析
2018/04/09 Javascript
微信小程序云开发 生成带参小程序码流程
2019/05/18 Javascript
ES6函数实现排它两种写法解析
2020/05/13 Javascript
使用 Github Actions 自动部署 Angular 应用到 Github Pages的方法
2020/07/20 Javascript
[47:55]Ti4第二日主赛事败者组 NaVi vs EG 1
2014/07/20 DOTA
[02:08]什么藏在DOTA2 TI9“小紫本”里?斧王历险记告诉你!
2019/05/17 DOTA
Python中正则表达式的详细教程
2015/04/30 Python
Python编程中字符串和列表的基本知识讲解
2015/10/14 Python
详解Python文本操作相关模块
2017/06/22 Python
python 2.7 检测一个网页是否能正常访问的方法
2018/12/26 Python
Python常见数据类型转换操作示例
2019/05/08 Python
xadmin使用formfield_for_dbfield函数过滤下拉表单实例
2020/04/07 Python
Omio意大利:全欧洲低价大巴、火车和航班搜索和比价
2017/12/02 全球购物
C语言50道问题
2014/10/23 面试题
JPA的特点
2014/10/25 面试题
媒体宣传策划方案
2014/05/25 职场文书
2015财务年终工作总结范文
2015/05/22 职场文书
运动会3000米加油稿
2015/07/21 职场文书
2015年教务主任工作总结
2015/07/22 职场文书
心理健康教育培训研修感言
2015/11/18 职场文书
详解redis在微服务领域的贡献
2021/10/16 Redis
利用js实现简单开关灯代码
2021/11/23 Javascript