偶然发现linux系统附带的一个数独游戏,打开玩了几把。无奈是个数独菜鸟,以前没玩过,根本就走不出几步就一团浆糊了。

于是就打算借助计算机的强大运算力来暴力解数独,还是很有乐趣的。

下面就记录一下我写解数独程序的一些思路和心得。

一.数独游戏的基本解决方法

编程笼统的来说,就是个方法论。不论什么程序,都必须将问题的解决过程分解成计算机可以实现的若干个简单方法。俗话说,大道至简。对于只能明白0和1的计算机来说,就更需要细分步骤,一步一步的解决问题了。

首先来思考一下解数独的基本概念。

数独横九竖九共八十一个格子,同时又分为9个九宫格。规则很简单——需要每一个格中的数字,都保证与其所在横排和竖排以及九宫格内无相同数字。

所以我们的大概思路就是,从第一个空格开始试着填数,从 1 开始填,如果 1 不满足横排竖排九宫格无重复的话,就再填入 2 ,以此类推,直到填入一个暂时满足规则的数,中断此格,移动到下一个空格重复这个过程。

如果到达某个空格发现已经无数可选了,说明前面某一格填错了,那就返回上一格,从上一格的中断处继续往 9 尝试,直到这样回朔到填错的那一格。

这样的话,我们就可以整理出重要的步骤了:

  • 寻找到下一个空格
  • 轮流填入格中数字 1 到 9
  • 递归判断填入数是否符合规则

二.程序

首先测试数独使用的是芬兰数学家因卡拉花费3个月时间设计出的世界上迄今难度最大的数独。如下

将空格用 0 表示,同时将数独表示成嵌套的列表,这样每格的行数和列数就正好是列表中每个对应数的索引。

程序如下:

 #coding=utf-8
import datetime
class solution(object):
def __init__(self,board):
self.b = board
self.t = 0 def check(self,x,y,value):#检查每行每列及每宫是否有相同项
for row_item in self.b[x]:
if row_item == value:
return False
for row_all in self.b:
if row_all[y] == value:
return False
row,col=x/3*3,y/3*3
row3col3=self.b[row][col:col+3]+self.b[row+1][col:col+3]+self.b[row+2][col:col+3]
for row3col3_item in row3col3:
if row3col3_item == value:
return False
return True def get_next(self,x,y):#得到下一个未填项
for next_soulu in range(y+1,9):
if self.b[x][next_soulu] == 0:
return x,next_soulu
for row_n in range(x+1,9):
for col_n in range(0,9):
if self.b[row_n][col_n] == 0:
return row_n,col_n
return -1,-1 #若无下一个未填项,返回-1 def try_it(self,x,y):#主循环
if self.b[x][y] == 0:
for i in range(1,10):#从1到9尝试
self.t+=1
if self.check(x,y,i):#符合 行列宫均无条件 的
self.b[x][y]=i #将符合条件的填入0格
next_x,next_y=self.get_next(x,y)#得到下一个0格
if next_x == -1: #如果无下一个0格
return True #返回True
else: #如果有下一个0格,递归判断下一个0格直到填满数独
end=self.try_it(next_x,next_y)
if not end: #在递归过程中存在不符合条件的,即 使try_it函数返回None的项
self.b[x][y] = 0 #回朔到上一层继续
else:
return True def start(self):
begin = datetime.datetime.now()
if self.b[0][0] == 0:
self.try_it(0,0)
else:
x,y=self.get_next(0,0)
self.try_it(x,y)
for i in self.b:
print i
end = datetime.datetime.now()
print '\ncost time:', end - begin
print 'times:',self.t
return s=solution([[8,0,0,0,0,0,0,0,0],
[0,0,3,6,0,0,0,0,0],
[0,7,0,0,9,0,2,0,0],
[0,5,0,0,0,7,0,0,0],
[0,0,0,8,4,5,7,0,0],
[0,0,0,1,0,0,0,3,0],
[0,0,1,0,0,0,0,6,8],
[0,0,8,5,0,0,0,1,0],
[0,9,0,0,0,0,4,0,0]])
s.start()

值得注意的是使用的递归判断能够很巧妙的在走错分支时回朔到上一层。具体实现是通过 for 循环来从 1 到 9 不断填入数字同时达到记录中断点的作用。通过下一层的返回值来确定是否回朔。

程序输出如下:

[8, 1, 2, 7, 5, 3, 6, 4, 9]
[9, 4, 3, 6, 8, 2, 1, 7, 5]
[6, 7, 5, 4, 9, 1, 2, 8, 3]
[1, 5, 4, 2, 3, 7, 8, 9, 6]
[3, 6, 9, 8, 4, 5, 7, 2, 1]
[2, 8, 7, 1, 6, 9, 5, 3, 4]
[5, 2, 1, 9, 7, 4, 3, 6, 8]
[4, 3, 8, 5, 2, 6, 9, 1, 7]
[7, 9, 6, 3, 1, 8, 4, 5, 2] cost time: 0:00:00.060687
times: 45360

可以看到程序虽然运算次数比较多,但是速度还是很快的。

使用python解数独的更多相关文章

  1. 解数独(Python)

    0.目录 1.介绍 2.一些通用函数 3.全局变量(宏变量) 4.数独预处理(约束传播) 5.解数独(深度优先搜索+最小代价优先) 6.主函数 7.总代码 1.介绍 数独是一个非常有趣味性的智力游戏, ...

  2. 旁友数独会伐啦?python秒解数独了解下伐啦?

    前几天和隔壁邻居玩斗地主被发现了,牌被没收了,斗地主是斗不了了,但我还想和邻居玩耍.如果你还想斗斗地主,戳:趁老王不在,和隔壁邻居斗斗地主,比比大小 想破脑袋终于让我想到一个游戏,数独!什么叫数独?数 ...

  3. LeetCode37 使用回溯算法实现解数独,详解剪枝优化

    本文始发于个人公众号:TechFlow,原创不易,求个关注 数独是一个老少咸宜的益智游戏,一直有很多拥趸.但是有没有想过,数独游戏是怎么创造出来的呢?当然我们可以每一关都人工设置,但是显然这工作量非常 ...

  4. python 解压 压缩包

    转 http://m.blog.csdn.net/blog/wice110956/26597179# 这里讨论使用Python解压如下五种压缩文件: .gz .tar  .tgz .zip .rar ...

  5. 用C++实现的解数独(Sudoku)程序

    我是一个C++初学者,控制台实现了一个解数独的小程序. 代码如下: //"数独游戏"V1.0 //李国良于2016年11月11日编写完成 #include <iostream ...

  6. python解无忧公主的数学时间编程题001.py

    python解无忧公主的数学时间编程题001.py """ python解无忧公主的数学时间编程题001.py http://mp.weixin.qq.com/s?__b ...

  7. python解无忧公主的数学时间097.py

    python解无忧公主的数学时间097.py """ python解无忧公主的数学时间097.py codegay 2016年3月30日 00:17:26 http:// ...

  8. python解无忧公主数学题107.py

    python解无忧公主数学题107.py """ python解无忧公主数学题107.py http://mp.weixin.qq.com/s?__biz=MzI5ODE ...

  9. python解无忧公主数学题108

    """ python解无忧公主数学题108回文.py 题目来源: http://mp.weixin.qq.com/s?__biz=MzI5ODEwMDQyNw==& ...

随机推荐

  1. asp.net中listview下嵌套gridview

    最近在上软件工程实践课程,想做一个类似于QQ空间或者朋友圈一样的效果.即显示所有好友发送的动态以及动态下回复的信息. 自己YY了一种方法,一开始以为不能达到效果,研究了2个小时终于实现了,感觉效果还是 ...

  2. window编程之win程序框架

    int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmd ...

  3. 关于adb重启的一些问题

    有时候我们在使用eclipse启动虚拟机进行程序测试的时候会提示,要我们重启adb和eclipse,这个时候,重启adb的方式就是,使用cmd定位到adb所在的文件夹,然后输入指令:adb kill- ...

  4. 【转】Python 中 Iterator和Iterable的区别

    Python中 list,truple,str,dict这些都可以被迭代,但他们并不是迭代器.为什么? 因为和迭代器相比有一个很大的不同,list/truple/map/dict这些数据的大小是确定的 ...

  5. C#的数据类型、数据类型的转化

    一.c#有15个预定义类型,其中13个是值类型,两个是引用类型(string 和 object)这里主要说明整型.浮点型.布尔型以及引用型 1.整型数据 2.浮点型 浮点型从精度有低到高有float. ...

  6. Maven的声明周期(Lifecycle )和命令(Phase)

    生命周期(Lifecycle ) Maven有三套相互独立的生命周期(Lifecycle ): Clean Lifecycle:做一些清理工作: Default Lifecycle:构建的核心部分.编 ...

  7. c语言二叉树的递归建立

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include <malloc.h&g ...

  8. 1754: [Usaco2005 qua]Bull Math

    1754: [Usaco2005 qua]Bull Math Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 398  Solved: 242[Submit ...

  9. (102, "Incorrect syntax near '-'.DB-Lib error message 102, severity 15:\nGen

    python 调用MSSQL存储过程,运行时报错 sql="exec spname %s,%s"%(param1,param2) 这是错误的调用存储过程的语句,param1和par ...

  10. [原创]HBase学习笔记(1)-安装和部署

    HBase安装和部署 使用的HBase版本是1.2.4 1.安装步骤(默认hdfs已安装好) # 下载并解压安装包 cd tools/ tar -zxf hbase-1.2.4-bin.tar.gz ...