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 Celery定时任务的示例
Mar 13 Python
详解Django之admin组件的使用和源码剖析
May 04 Python
Python Web编程之WSGI协议简介
Jul 18 Python
在python中实现对list求和及求积
Nov 14 Python
Python 从列表中取值和取索引的方法
Dec 25 Python
在pycharm中设置显示行数的方法
Jan 16 Python
python多进程读图提取特征存npy
May 21 Python
Python爬虫 scrapy框架爬取某招聘网存入mongodb解析
Jul 31 Python
python对csv文件追加写入列的方法
Aug 01 Python
Python高级编程之继承问题详解(super与mro)
Nov 19 Python
Python opencv相机标定实现原理及步骤详解
Apr 09 Python
Django缓存Cache使用详解
Nov 30 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获取目录所有文件并将结果保存到数组(实例)
2013/10/25 PHP
zf框架的db类select查询器join链表使用示例(zend框架)
2014/03/14 PHP
php session 写入数据库
2016/02/13 PHP
javascript深入理解js闭包
2010/07/03 Javascript
setTimeout和setInterval的区别你真的了解吗?
2011/03/31 Javascript
JavaScript常用脚本汇总(一)
2015/03/04 Javascript
AngularJS控制器之间的数据共享及通信详解
2016/08/01 Javascript
JavaScript组成、引入、输出、运算符基础知识讲解
2016/12/08 Javascript
JavaScript常用正则验证函数实例小结【年龄,数字,Email,手机,URL,日期等】
2017/01/23 Javascript
js 倒计时(高效率服务器时间同步)
2017/09/12 Javascript
JQuery扩展对象方法操作示例
2018/08/21 jQuery
QRCode.js二维码生成并能长按识别
2018/10/16 Javascript
Node.js如何优雅的封装一个实用函数的npm包的方法
2019/04/29 Javascript
关于微信小程序map组件z-index的层级问题分析
2019/07/09 Javascript
浅探express路由和中间件的实现
2019/09/30 Javascript
[01:05:56]Liquid vs VP Supermajor决赛 BO 第二场 6.10
2018/07/04 DOTA
[47:42]完美世界DOTA2联赛PWL S2 GXR vs Ink 第一场 11.19
2020/11/20 DOTA
Python基于twisted实现简单的web服务器
2014/09/29 Python
python的keyword模块用法实例分析
2015/06/30 Python
Python实现列表删除重复元素的三种常用方法分析
2017/11/24 Python
Python 反转字符串(reverse)的方法小结
2018/02/20 Python
Python中elasticsearch插入和更新数据的实现方法
2018/04/01 Python
python flask实现分页的示例代码
2018/08/02 Python
python绘制多个曲线的折线图
2020/03/23 Python
Python-jenkins模块获取jobs的执行状态操作
2020/05/12 Python
django 数据库返回queryset实现封装为字典
2020/05/19 Python
纯CSS改变webkit内核浏览器的滚动条样式
2014/04/17 HTML / CSS
CSS3制作圆形滚动进度条动画的示例
2020/11/05 HTML / CSS
解释一下钝化(Swap out)
2016/12/26 面试题
学生自我鉴定范文
2013/10/04 职场文书
自荐信格式写作方法有哪些呢
2013/11/20 职场文书
大学生个人实习的自我评价
2014/02/15 职场文书
暑期社会实践个人总结
2015/03/06 职场文书
毕业证明书
2015/06/19 职场文书
听证会主持词
2015/07/03 职场文书
BCL经典机 SONY ICF-5900W电路分析
2022/04/24 无线电