python3.6数独问题的解决

算法比较暴力,直接用穷举的方式一个一个去试,所以程序运行时间会比较长,运行时间视数独而定。
不过从一开始到运行成功,整个过程却是一波三折,设计算法就花了不少时间,然后就是不断地去调试,找bug。刚开始的时候为了省事直接在sudoku类中递归调用blank,但是老哥还是too young too simple,sometimes navie,计算量实在是太大了,后面编译器直接抛出 “RecursionError: maximum recursion depth exceeded while calling a Python object” 超过最大递归深度的错误。在把递归深度改到100000之后,又出现了堆栈溢出问题。当然,解决办法也是相当地暴力:把递归放入while循环中,一旦符合条件就直接exit(0),整个程序直接gg,然后退出结束。
当然,算法还可以再优化一下,可以不用那么暴力,先列出可能的值然后再填入,这样可以大大缩小整个程序的运行时间,但是……懒得优化了,就这样吧,又不是不能用(笑~)。

运行结果:

再试一个其他的数独:

这回就快得多了,11秒就完成了,比第一个数独不知高到哪里去了

代码如下所示:

import copy
import time

t1=time.time()
origin = [[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, 0, 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]]

class sudoku:
 def debug(self): # 调试
 for list in origin:
  print(list)
 print("\n")

 def check_repetition(self,list):#判断表中是否有重复值,0除外
 flag=0
 for i in range(1,10):
  if list.count(i)>=2:
  return 1
  else:
  flag=flag+1
 if flag==9:
  return 0

 def check_row(self,row):#检测横向是否有重复值,无则为返回0,有则返回1
 list = origin[row] # 横向
 r1 = self.check_repetition(list)
 if r1 == 0:
  return 0
 else :
  return 1

 def check_column(self,column):#检测纵向是否重复值,无则为返回0,有则返回1
 list = [] # 纵向
 for num in origin:
  list.append(num[column])
 r2 = self.check_repetition(list)
 if r2==0:
  return 0
 else:
  return 1

 def check_square(self,x,y):#检测九宫格是否有重复值,无则为返回0,有则返回1
 x,y=y,x
 if x>=9 or y>=9:
  return
 square = []#九宫格
 for i in range(0+y//3*3, 3+y//3*3):
  for j in range(0+x//3*3, 3+x//3*3):
  square.append(origin[i][j])
 r3 = self.check_repetition(square)
 if r3==0:
  return 0
 else:
  return 1

 def check(self,x,y):#检测是否有重复值,无则为0,有则不为0
 r1 = self.check_row(x)
 r2 = self.check_column(y)
 r3 = self.check_square(x, y)
 result=r1+r2+r3
 return result

 def get_next(self): # 获得下一个空值,返回row,column值
 i = 0
 for list in origin:
  try: # 当0不在列表中时,跳过
  column = list.index(0)
  row = origin.index(list)
  res = (row, column)
  return res
  except ValueError:
  i = i + 1
  if i == 9:
   t2=time.time()
   print("总用时={}".format(t2 - t1))
   exit(0)

 def poi(self,row, column): # 位置修正
 if row == 0 and column == -1:
  return
 if row == 8 and column == 9:
  return
 if column == -1:
  column = 8
  row = row - 1
 if column == 9:
  column = 0
  row = row - 1
 return (row, column)

 def get_last(self,row, column):
 origin[row].insert(column, 0)
 origin[row].pop(column + 1)
 column = column - 1 # 获得上一个已填值的行、列位置
 row, column = self.poi(row, column)#位置修正
 r = origin[row][column] * compare[row][column]
 while r != 0:
  column = column - 1
  row, column = self.poi(row, column)
  r = origin[row][column] * compare[row][column]
 return (row, column)

 def blank(self):
 try:
  row,column=self.get_next()
 except TypeError:#已填完
  exit(0)
 j=0
 flag=0
 for i in range(1,10):
  origin[row].insert(column,i)
  origin[row].pop(column+1)
  self.debug()
  r = self.check(row, column)
  if r==0:#无重复值
  return
  else:
  j = j + 1
  if j==9:
   flag=1
   break
 if flag==1:
  row, column = self.get_last(row, column)
  value=origin[row][column]
  self.debug()
  while value == 9:
  row, column = self.get_last(row, column)
  value = origin[row][column]
  self.debug()
  while value<9:
  for k in range(value+1,10):
   origin[row].insert(column, k)
   origin[row].pop(column + 1)
   self.debug()
   r=self.check(row,column)
   if r!=0:#有重复
   if k==9:
    row, column = self.get_last(row, column)
    value=origin[row][column]
    self.debug()
    while value==9:
    row, column = self.get_last(row, column)
    value = origin[row][column]
    self.debug()
    break
   else:
   return

if __name__=="__main__":
 compare = copy.deepcopy(origin)
 sudoku = sudoku()
 while 1:
 sudoku.blank()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • python实现自动解数独小程序

    跟朋友最近聊起来数独游戏,突发奇想使用python编写一个自动计算数独解的小程序. 数独的规则不再过多阐述,在此描述一下程序的主要思路: (当前程序只针对于简单的数独,更复杂的还待深入挖掘) 1.计算当前每个空格可能的取值集合,并将空格顺序值对应取值集合置于字典中: 2.对取值集合位数为1,即空格处为单一取值的进行赋值,(填入动作),重复1刷新字典直到字典为空位置: 当前实现如下: 1.将数独输入列表中,并定义函数count_candinate_number(j)根据数独规则计算每一个为0的位置

  • python实现数独算法实例

    本文实例讲述了python实现数独算法的方法.分享给大家供大家参考.具体如下: # -*- coding: utf-8 -*- ''' Created on 2012-10-5 @author: Administrator ''' from collections import defaultdict import itertools a = [ [ 0, 7, 0, 0, 0, 0, 0, 0, 0], #0 [ 5, 0, 3, 0, 0, 6, 0, 0, 0], #1 [ 0, 6, 2

  • 简单实现python数独游戏

    网上看到一个python写的数独,很好玩,分享给大家. import random import itertools from copy import deepcopy def make_board(m = 3): numbers = list(range(1, m**2 + 1)) board = None while board is None: board = attempt_board(m, numbers) return board def attempt_board(m, numbe

  • Python判断有效的数独算法示例

    本文实例讲述了Python判断有效的数独算法.分享给大家供大家参考,具体如下: 一.题目 判断一个 9x9 的数独是否有效.只需要根据以下规则,验证已经填入的数字是否有效即可. 1. 数字 1-9 在每一行只能出现一次. 2. 数字 1-9 在每一列只能出现一次. 3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次. 数独部分空格内已填入了数字,空白格用 '.' 表示. 例1: 输入: [ ["5","3",".","

  • Python如何判断数独是否合法

    介绍 该数独可能只填充了部分数字,其中缺少的数字用 . 表示. 注意事项 一个合法的数独(仅部分填充)并不一定是可解的.我们仅需使填充的空格有效即可. 解体思路 将数独按照行.列和块进行预处理,然后分别判断是否合法. 利用Python的表达式推导,匿名函数和all函数可以很方便的进行处理. 代码 class Solution: # @param board, a 9x9 2D array # @return a boolean def isValidSudoku(self, board): ro

  • python实现数独游戏 java简单实现数独游戏

    使用python和java实现数独游戏,有比较才有收获哦. 1.Python版 #--coding:utf-8-- import random import itertools from copy import deepcopy def make_board(m=3): numbers = list(range(1,m**2+1)) #可能出现的数字为1-9 board = None #board是数度二维列表 while board is None: board = get_board(m,n

  • python实现解数独程序代码

    偶然发现linux系统附带的一个数独游戏,打开玩了几把.无奈是个数独菜鸟,以前没玩过,根本就走不出几步就一团浆糊了. 于是就打算借助计算机的强大运算力来暴力解数独,还是很有乐趣的. 下面就记录一下我写解数独程序的一些思路和心得. 一.数独游戏的基本解决方法 编程笼统的来说,就是个方法论.不论什么程序,都必须将问题的解决过程分解成计算机可以实现的若干个简单方法.俗话说,大道至简.对于只能明白0和1的计算机来说,就更需要细分步骤,一步一步的解决问题了. 首先来思考一下解数独的基本概念. 数独横九竖九

  • python3.6数独问题的解决

    算法比较暴力,直接用穷举的方式一个一个去试,所以程序运行时间会比较长,运行时间视数独而定. 不过从一开始到运行成功,整个过程却是一波三折,设计算法就花了不少时间,然后就是不断地去调试,找bug.刚开始的时候为了省事直接在sudoku类中递归调用blank,但是老哥还是too young too simple,sometimes navie,计算量实在是太大了,后面编译器直接抛出 "RecursionError: maximum recursion depth exceeded while cal

  • 基于centos7 安装python3.6.4出错的解决方法

    错误:zipimport.ZipImportError: can't decompress data; zlib not available 解决方法:从错误信息分析,就是缺少了zlib的解压缩类库,安装即可. 执行 yum -y install zlib* 安装完成之后,重新安装即可,所有的问题都已经正常解决了!!! 以上这篇基于centos7 安装python3.6.4出错的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们. 您可能感兴趣的文章: 在cen

  • 安装python3的时候就是输入python3死活没有反应的解决方法

    我用brew安装python3 装完了发现 输入python3毫无反应,检查了 $PATH 也没有任何问题 这个时候回去看安装过程,发现安装时有一个错误: ERROR:The `brew link` step did not complete successfully The formula built, but is not symlinked into /usr/local Could not symlink lib/pkgconfig/python-3.6.pc (好像是这个,安装的时候忘

  • Centos 升级到python3后pip 无法使用的解决方法

    一. 问题 [root@localhost local]# pip -bash: pip: command not found pip无法使用. 二. 系统环境 Centos 6.6 Python 3.5.2 三. 解决方法 设置软连接. 1.查找pip所在位置 [root@xxx local]# find / -name "pip" /Python-3.5.2/Tools/msi/pip /usr/bin/pip /usr/local/python3.5.2/bin/pip /usr

  • WINDOWS 同时安装 python2 python3 后 pip 错误的解决方法

    再之前同时安装 python 后 只需把环境变量PATH 里面改为 PATH=C:\Python36-32\Scripts\;C:\Python36-32\;C:\Python27\;C:\Python27\Scripts 然后把python3安装后的文件按照如下修改: C:\Python36-32\Scripts\pip.exe 改为 C:\Python36-32\Scripts\pip3.exe C:\Python36-32\python.exe 改为 C:\Python36-32\pyth

  • python3安装crypto出错及解决方法

    首先我用的python3.5的版本 问题的由来,我想通过python去实现RSA加密算法时,破解某网站的js加密认证,网上说需要安装pycrypto,我就去进行pip安装了 pip install pycrypto 错误信息如下 error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build 经过网上查询信息,才知道这个库以及不再更新了,所以安装的时候会出一些错,因为c++编译环境有所问题

  • Mac在python3环境下安装virtualwrapper遇到的问题及解决方法

    前言 我在使用mac安装virtualwrapper的时候遇到了问题,搞了好长时间,才弄好,在这里总结一下分享出来,供遇到相同的问题的朋友使用,少走些弯路. 问题说明: Mac默认系统的python2,而我自己用的是brew安装的python3 下面是我安装过程中出现的问题 1. 安装virtualwrapper 打开终端,输入如下的命令 pip3 install virtualenv pip3 install virtualenvwrapper 2. 在配置文件~/.bash_profile中

  • 关于python3.9安装wordcloud出错的问题及解决办法

    本文给大家分享python3.9安装wordcloud出错解决经历,感兴趣的朋友一起看看吧 晚上闲的无聊,就想安装个词云玩玩,但是安装失败,出现命令在退出时发生错误,在网上找了很多的解决办法,但是一一不管用,试了在pycharm->settings->project interrupt 进行安装,不料还是报错, 我开始是用pip install --upgradepip 和pip install --upgrade setuptools来升级我的pip,但是没有什么用,还是一如既往的报错. 此

  • python3.7安装matplotlib失败问题的完美解决方法

    目录 起因: 问题描述 解决方案: 总结 起因: 刚学习机器学习,需要用到matplotlib这个库,结果安装失败了 问题描述 一开始在pycharm里进行安装,失败了,查看日志,没有error提示,就去cmd尝试pip install matplotlib 结果依旧失败 pip install matplotlib 按照error提示大概可以知道pip库版本太久了,所以需要升级pip的版本,在cmd进入python的Scripts文件夹输入以下命令对pip库进行升级 python -m pip

  • 同时安装Python2 & Python3 cmd下版本自由选择的方法

    系统:win7 python2.7,python3.6同时安装,于是问题来了,python27与python36文件夹下的文件名都是python.exe 这样在cmd下,直接输入python,自动执行python27 搜索了网上的解决方案,大多是将两个python.exe改名,分别改为python2,python3加以区别 但是这样会造成很多问题,比如运行IDLE时,python27会自动重建一个python.exe文件...也就是说之前改了也白改 最后找到一个合理的解决方案:使用python自

随机推荐