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的dict字典结构操作方法学习笔记
May 07 Python
Python决策树分类算法学习
Dec 22 Python
python遍历文件夹找出文件夹后缀为py的文件方法
Oct 21 Python
对Python的多进程锁的使用方法详解
Feb 18 Python
scrapy-redis的安装部署步骤讲解
Feb 27 Python
windows10下安装TensorFlow Object Detection API的步骤
Jun 13 Python
python实现证件照换底功能
Aug 20 Python
Python @property使用方法解析
Sep 17 Python
Django 限制访问频率的思路详解
Dec 24 Python
From CSV to SQLite3 by python 导入csv到sqlite实例
Feb 14 Python
Python 实现键盘鼠标按键模拟
Nov 18 Python
Python 数据可视化工具 Pyecharts 安装及应用
Apr 20 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
PHP4 与 MySQL 数据库操作函数详解
2006/10/09 PHP
php合并数组array_merge函数运算符加号与的区别
2008/10/31 PHP
Php Cookie的一个使用注意点
2008/11/08 PHP
解析phpstorm + xdebug 远程断点调试
2013/06/20 PHP
PhpDocumentor 2安装以及生成API文档的方法
2014/05/21 PHP
基于Laravel(5.4版本)的基本增删改查操作方法
2019/10/11 PHP
PHP cookie与session会话基本用法实例分析
2019/11/18 PHP
Laravel 微信小程序后端实现用户登录的示例代码
2019/11/26 PHP
基于jquery的文本框与autocomplete结合使用(asp.net+json)
2012/05/30 Javascript
使用JS取得焦点(focus)元素代码
2014/03/22 Javascript
jQuery操作元素css样式的三种方法
2014/06/04 Javascript
JavaScript使用concat连接数组的方法
2015/04/06 Javascript
JavaScript淡入淡出渐变简单实例
2015/08/06 Javascript
jquery实现动画菜单的左右滚动、渐变及图形背景滚动等效果
2015/08/25 Javascript
jquery实现加载进度条提示效果
2015/11/23 Javascript
JS关闭窗口时产生的事件及用法示例
2016/08/20 Javascript
微信小程序 两种滑动方式(横向滑动,竖向滑动)详细及实例代码
2017/01/13 Javascript
基于Bootstrap框架实现图片切换
2017/03/10 Javascript
BootStrap表单控件之文本域textarea
2017/05/23 Javascript
bootstrap中日历范围选择插件daterangepicker的使用详解
2018/04/17 Javascript
jQuery+CSS实现的标签页效果示例【测试可用】
2018/08/14 jQuery
vue实现户籍管理系统
2020/05/29 Javascript
用Python从零实现贝叶斯分类器的机器学习的教程
2015/03/31 Python
使用Python中的greenlet包实现并发编程的入门教程
2015/04/16 Python
Python实现针对中文排序的方法
2017/05/09 Python
python3实现163邮箱SMTP发送邮件
2018/05/22 Python
python定向爬虫校园论坛帖子信息
2018/07/23 Python
Django文件存储 默认存储系统解析
2019/08/02 Python
详解CSS3中Media Queries的相关使用
2015/07/17 HTML / CSS
Linux内核产生并发的原因
2012/07/13 面试题
《长江之歌》教学反思
2014/04/17 职场文书
入党积极分子评语
2014/05/04 职场文书
人民调解协议书范本
2014/10/11 职场文书
申报材料格式
2014/12/30 职场文书
委托书的样本
2015/01/28 职场文书
2016大学生求职自荐信范文
2016/01/28 职场文书