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中文分词,使用结巴分词对python进行分词(实例讲解)
Nov 14 Python
Python pymongo模块用法示例
Mar 31 Python
使用Python设计一个代码统计工具
Apr 04 Python
对python xlrd读取datetime类型数据的方法详解
Dec 26 Python
Python字符串的全排列算法实例详解
Jan 07 Python
python日志logging模块使用方法分析
May 23 Python
Python求离散序列导数的示例
Jul 10 Python
Python flask路由间传递变量实例详解
Jun 03 Python
Python使用requests模块爬取百度翻译
Aug 25 Python
Pyecharts 中Geo函数常用参数的用法说明
Feb 01 Python
Django如何创作一个简单的最小程序
May 12 Python
使用pandas模块实现数据的标准化操作
May 14 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之数据库操作详解及乱码解决!
2007/01/02 PHP
PHP句法规则详解 入门学习
2011/11/09 PHP
php实现单链表的实例代码
2013/03/22 PHP
PHP获取用户客户端真实IP的解决方案
2016/10/10 PHP
thinkphp5 加载静态资源路径与常量的方法
2017/12/24 PHP
PHP面向对象五大原则之接口隔离原则(ISP)详解
2018/04/04 PHP
PHP设计模式之单例模式原理与实现方法分析
2018/04/25 PHP
PHP获取对象属性的三种方法实例分析
2019/01/03 PHP
解决laravel5.4下的group by报错的问题
2019/10/16 PHP
ExtJS 简介 让你知道extjs是什么
2008/12/29 Javascript
Mootools 1.2教程 Tooltips
2009/09/15 Javascript
jquery animate 动画效果使用说明
2009/11/04 Javascript
30个最佳jQuery Lightbox效果插件分享
2011/04/11 Javascript
javascript 进阶篇2 CSS XML学习
2012/03/14 Javascript
网站如何做到完全不需要jQuery也可以满足简单需求
2013/06/27 Javascript
使用js对select动态添加和删除OPTION示例代码
2013/08/12 Javascript
js中一个函数获取另一个函数返回值问题探讨
2013/11/21 Javascript
谈谈基于iframe、FormData、FileReader三种无刷新上传文件的方法
2015/12/03 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
2016/03/01 Javascript
动态的9*9乘法表效果的实现代码
2016/05/16 Javascript
Vue页面骨架屏注入方法
2018/05/13 Javascript
element-ui 上传图片后清空图片显示的实例
2018/09/04 Javascript
JavaScript类的继承操作实例总结
2018/12/20 Javascript
微信小程序如何调用图片接口API并居中显示
2019/06/29 Javascript
openlayers实现地图测距测面
2020/09/25 Javascript
Python中list列表的一些进阶使用方法介绍
2015/08/15 Python
Python根据指定日期计算后n天,前n天是哪一天的方法
2018/05/29 Python
python 一篇文章搞懂装饰器所有用法(建议收藏)
2019/08/23 Python
pytorch 实现查看网络中的参数
2020/01/06 Python
使用placeholder属性设置input文本框的提示信息
2020/02/19 HTML / CSS
Crocs美国官方网站:卡骆驰洞洞鞋
2017/08/04 全球购物
外企财务年会演讲稿
2014/01/03 职场文书
幼儿园优秀班主任事迹材料
2014/05/14 职场文书
2014年学校国庆主题活动方案
2014/09/16 职场文书
2015年度高中教师工作总结
2015/05/26 职场文书
MATLAB 如何求取离散点的曲率最大值
2021/04/16 Python