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 获取本机ip地址的两个方法
Feb 25 Python
从零学python系列之浅谈pickle模块封装和拆封数据对象的方法
May 23 Python
详解Python的单元测试
Apr 28 Python
python中引用与复制用法实例分析
Jun 04 Python
Python中for循环和while循环的基本使用方法
Aug 21 Python
Python编程pygame模块实现移动的小车示例代码
Jan 03 Python
python 调用钉钉机器人的方法
Feb 20 Python
python实现连连看辅助之图像识别延伸
Jul 17 Python
python实现简单俄罗斯方块
Mar 13 Python
TensorFlow-gpu和opencv安装详细教程
Jun 30 Python
详解vscode实现远程linux服务器上Python开发
Nov 10 Python
Python利用myqr库创建自己的二维码
Nov 24 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部分常见问题总结
2008/03/27 PHP
PHP 截取字符串函数整理(支持gb2312和utf-8)
2010/02/16 PHP
PHP 第二节 数据类型之数组
2012/04/28 PHP
php使用curl发送json格式数据实例
2013/12/17 PHP
PHP书写格式详解(必看)
2016/05/23 PHP
YII框架常用技巧总结
2019/04/27 PHP
javaScript对象和属性的创建方法
2007/01/15 Javascript
jscript之Read an Excel Spreadsheet
2007/06/13 Javascript
Javascript实现滑块滑动改变值的实现代码
2013/04/12 Javascript
基于jquery插件实现常见的幻灯片效果
2013/11/01 Javascript
深入理解JavaScript系列(28):设计模式之工厂模式详解
2015/03/03 Javascript
基于jQuery实现响应式圆形图片轮播特效
2015/11/25 Javascript
JavaScript中setter和getter方法介绍
2016/07/11 Javascript
mui back 返回刷新页面的实例
2017/12/06 Javascript
JavaScript多种滤镜算法实现代码实例
2019/12/10 Javascript
Node.js 在本地生成日志文件的方法
2020/02/07 Javascript
Openlayers3实现车辆轨迹回放功能
2020/09/29 Javascript
python对excel文档去重及求和的实例
2018/04/18 Python
解决pandas无法在pycharm中使用plot()方法显示图像的问题
2018/05/24 Python
python使用Matplotlib画条形图
2020/03/25 Python
对python opencv 添加文字 cv2.putText 的各参数介绍
2018/12/05 Python
解决python打不开文件(文件不存在)的问题
2019/02/18 Python
django框架使用方法详解
2019/07/18 Python
Django中使用MySQL5.5的教程
2019/12/18 Python
Python字典添加,删除,查询等相关操作方法详解
2020/02/07 Python
Pytorch mask_select 函数的用法详解
2020/02/18 Python
numpy中生成随机数的几种常用函数(小结)
2020/08/18 Python
Python环境配置实现pip加速过程解析
2020/11/27 Python
HTML5中如何显示视频呢 HTML5视频播放demo
2013/06/08 HTML / CSS
物流管理专业毕业生自荐信
2014/03/04 职场文书
党员个人整改措施
2014/10/24 职场文书
世界卫生日宣传活动总结
2015/02/09 职场文书
2015年班干部工作总结
2015/04/29 职场文书
2016年社会主义核心价值观心得体会
2016/01/21 职场文书
再也不用花钱买漫画!Python爬取某漫画的脚本及源码
2021/06/09 Python
css3 文字断裂效果
2022/04/22 HTML / CSS