数独解题程序的python实现_使用Python编写程序求解数独游戏答案

原标题:使用Python编写程序求解数独游戏答案

问题描述:数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。

解题建议:遇到问题后,最好先手工推导和模拟一下,把思路理清楚,然后再动手写代码。

参考代码:

importrandom

definit():

# 初始状态,每个格内都是1-9之间的数字

grids = {(r, c):list(range(1,10))

forr inrange(9) forc inrange(9)}

# 根据文件中的位置和数字设置数独游戏初始状态

withopen('values.txt') asfp:

forline infp:

line = line.strip()

ifline =='0':

break

row, col, value = map(int, line.split(','))

grids[(row,col)] = value

returngrids

defeachGrid(grids, row, col, value):

tempValue = grids[(row,col)]

# 删除不可能的数字

ifisinstance(tempValue, list):

ifvalue intempValue:

tempValue.remove(value)

# 如果格内只有一个数字,就拿出来填充

iflen(tempValue) == 1:

grids[(row,col)] = tempValue[0]

defsolve(oldGrids):

grids = oldGrids.copy()

forr inrange(9):

forc inrange(9):

value = grids[(r,c)]

ifisinstance(value, int):

# 处理同一列

forrr inrange(9):

eachGrid(grids, rr, c, value)

# 处理同一行

forcc inrange(9):

eachGrid(grids, r, cc, value)

# 处理小九宫格内的数字

rowStart = r//3 * 3

colStart = c//3 * 3

forrr inrange(rowStart, rowStart+3):

forcc inrange(colStart, colStart+3):

eachGrid(grids, rr, cc, value)

elifisinstance(value, list) andlen(value)==1:

# 当前格内只有一个数了,拿出来填充

grids[(r,c)] = value[0]

returngrids

defoutput(grids):

'''输出grids中的内容'''

forrow inrange(9):

forcol inrange(9):

value = grids[(row,col)]

ifisinstance(value, int):

print(grids[(row,col)], end=' ')

else:

print(' ', end=' ')

print()

defcheck(grids):

'''检查grids是否满足数独游戏要求'''

forrc inrange(9):

row = {grids[(rc,c)] forc inrange(9)}

iflen(row) != 9:

return False

col = {grids[(r,rc)] forr inrange(9)}

iflen(col) != 9:

return False

forrow inrange(0,9,3):

forcol inrange(0,9,3):

value = {grids[(r,c)]

forr inrange(row,row+3)

forc inrange(col,col+3)}

iflen(value) != 9:

return False

return True

defmain(oldGrids):

grids = oldGrids.copy()

steps = 0

while True:

steps += 1

grids = solve(grids)

ifsteps > 20:

try:

position = [(r,c)

forr inrange(9) forc inrange(9)

ifisinstance(grids[(r,c)],list)][0]

grids[position] = random.choice(grids[position])

except:

grids = oldGrids.copy()

steps = 0

continue

ifall({isinstance(grids[(r,c)], int)

forr inrange(9) forc inrange(9)}):

ifcheck(grids):

returngrids

else:

# 当前选择无效,恢复原状,选择下一个

grids = oldGrids.copy()

steps = 0

grids = init()

output(grids)

result = main(grids)

print('='*30)

output(result)

print(check(result))

代码中使用的文本文件values.txt中内容格式,以第一行为例,0,2,9表示第0行第2列的初始数字为9:

运行结果一:

运行结果二:

运行结果三:

运行结果四:

------------我是分割线-------------

新书《Python程序设计开发宝典》封面与目录,已在天猫(清华大学出版社官方旗舰店)、亚马逊、当当、京东、互动出版网等各大网店全面上架。

第1章 管中窥豹:Python概述 14

1.1 Python是这样一种语言 14

1.2 Python版本之争 14

1.3 Python编程规范与代码优化建议 15

1.4 Python虚拟开发环境的搭建 17

1.5 Eclipse+PyDev环境搭建和使用 17

1.6 安装扩展库的几种方法 19

1.7 标准库与扩展库中对象的导入与使用 20

1.7.1 import 模块名 [as 别名] 20

1.7.2 from 模块名 import 对象名[ as 别名] 21

1.7.3 from 模块名 import * 21

1.7.4 模块导入时的搜索路径 22

1.8 编写与发布自己的包 23

1.9 Python程序伪编译与打包 25

1.10 从命令行参数和配置文件获取信息 27

第2章 万丈高楼平地起:运算符、表达式与内置对象 29

2.1 Python常用内置对象 29

2.1.1 常量与变量 30

2.1.2 数字 31

2.1.3 字符串 34

2.1.4 列表、元组、字典、集合 35

2.2 Python运算符与表达式 37

2.2.1 算术运算符 38

2.2.2 关系运算符 39

2.2.3 成员测试运算符in与同一性测试运算符is 40

2.2.4 位运算符与集合运算符 41

2.2.5 逻辑运算符 41

2.2.6 矩阵乘法运算符@ 42

2.2.7 补充说明 42

2.3 Python关键字简要说明 43

2.4 Python常用内置函数用法精要 44

2.4.1 类型转换与类型判断 47

2.4.2 最值与求和 51

2.4.3 基本输入输出 52

2.4.4 排序与逆序 55

2.4.5 枚举与迭代 56

2.4.6 map()、reduce()、filter() 57

2.4.7 range() 61

2.4.8 zip() 61

2.4.9 eval()、exec() 62

第3章 玄之又玄,众妙之门:详解Python序列结构 64

3.1 列表:打了激素的数组 64

3.1.1 列表创建与删除 65

3.1.2 列表元素访问 66

3.1.3 列表常用方法 67

3.1.4 列表对象支持的运算符 72

3.1.5 内置函数对列表的操作 74

3.1.6 使用列表模拟向量运算 75

3.1.7 列表推导式语法与应用案例 76

3.1.8 切片操作的强大功能 83

3.2 元组:轻量级列表 86

3.2.1 元组创建与元素访问 86

3.2.2 元组与列表的异同点 87

3.2.3 生成器推导式 88

3.3 字典:反映对应关系的映射类型 90

3.3.1 字典创建与删除 90

3.3.2 字典元素的访问 91

3.3.3 元素添加、修改与删除 92

3.3.4 标准库collections中与字典有关的类 93

3.4 集合:元素之间不允许重复 94

3.4.1 集合对象的创建与删除 95

3.4.2 集合操作与运算 95

3.4.3 不可变集合frozenset 97

3.4.4 集合应用案例 97

3.5 序列解包的多种形式和用法 100

3.6 标准库中的其他常用数据类型 102

3.6.1 枚举类型 102

3.6.2 数组类型 103

3.6.3 队列 103

3.6.4 具名元组 105

3.6.5 堆 106

第4章 反者,道之动:程序控制结构 108

4.1 条件表达式 108

4.2 选择结构 110

4.2.1 单分支选择结构 110

4.2.2 双分支选择结构 111

4.2.3 多分支选择结构 112

4.2.4 选择结构的嵌套 113

4.2.5 构建跳转表实现多分支选择结构 114

4.3 循环结构 114

4.3.1 for循环与while循环 115

4.3.2 break与continue语句 116

4.3.3 循环代码优化技巧 117

4.4 精彩案例赏析 118

第5章 代码复用技术(一):函数 126

5.1 函数定义与使用 126

5.1.1 基本语法 126

5.1.2 函数嵌套定义、可调用对象与修饰器 128

5.1.3 函数对象成员的动态性 132

5.1.4 函数递归调用 132

5.2 函数参数 134

5.2.1 位置参数 135

5.2.2 默认值参数 135

5.2.3 关键参数 137

5.2.4 可变长度参数 137

5.2.5 强制函数的某些参数必须以关键参数形式进行传值 138

5.2.6 强制函数的所有参数必须以位置参数 139

5.2.7 传递参数时的序列解包 140

5.2.8 标注函数参数与返回值类型 142

5.3 变量作用域 142

5.3.1 全局变量与局部变量 142

5.3.2 nonlocal变量 145

5.4 lambda表达式 146

5.5 生成器函数设计要点 148

5.6 偏函数与函数柯里化 150

5.7 单分发器与泛型函数 152

5.8 协程函数 153

5.9 注册程序退出时必须执行的函数 155

5.10 回调函数原理与实现 156

5.11 精彩案例赏析 156

第6章 代码复用技术(二):面向对象程序设计 184

6.1 类的定义与使用 184

6.1.1 基本语法 184

6.1.2 type类 185

6.1.3 定义带修饰器的类 186

6.2 数据成员与成员方法 187

6.2.1 私有成员与公有成员 187

6.2.2 数据成员 189

6.2.3 成员方法、类方法、静态方法、抽象方法 190

6.2.4 属性 192

6.2.5 类与对象的动态性、混入机制 194

6.3 继承、多态、依赖注入 196

6.3.1 继承 196

6.3.2 多态 198

6.3.3 依赖注入技术的不同实现方法 199

6.4 特殊方法与运算符重载 202

6.5 精彩案例赏析 204

6.5.1 自定义队列 204

6.5.2 自定义栈 208

6.5.3 自定义集合 210

6.5.4 自定义数组 216

6.5.5 自定义双链表 221

6.5.6 自定义常量类 223

6.5.7 自定义不允许修改值的字典 224

6.5.8 自定义支持with关键字的类 225

第7章 文本处理(一):字符串 226

7.1 字符串编码格式简介 227

7.2 转义字符与原始字符串 228

7.3 字符串格式化 229

7.3.1 使用%符号进行格式 229

7.3.2 使用format()方法进行字符串格式化 231

7.3.3 格式化的字符串常量 232

7.3.4 使用Template模板进行格式化 232

7.4 字符串常用操作 233

7.4.1 find()、rfind()、index()、rindex()、count() 233

7.4.2 split()、rsplit()、partition()、rpartition() 235

7.4.3 join() 236

7.4.4 lower()、upper()、capitalize()、title()、swapcase() 237

7.4.5 replace()、maketrans()、translate() 238

7.4.6 strip()、rstrip()、lstrip() 239

7.4.7 startswith()、endswith() 239

7.4.8 isalnum()、isalpha()、isdigit()、isdecimal()、isnumeric()、isspace()、isupper()、islower() 240

7.4.9 center()、ljust()、rjust()、zfill() 241

7.4.10 字符串对象支持的运算符 241

7.4.11 适用于字符串对象的内置函数 243

7.4.12 字符串对象的切片操作 245

7.5 其他有关模块 245

7.5.1 textwrap模块 245

7.5.2 zlib模块提供的压缩功能 248

7.6 字符串常量 249

7.7 可变字符串 250

7.8 中英文分词 251

7.9 汉字到拼音的转换 252

7.10 精彩案例赏析 253

第8章 文本处理(二):正则表达式 256

8.1 正则表达式语法 256

8.1.1 正则表达式基本语法 256

8.1.2 正则表达式扩展语法 257

8.1.3 正则表达式锦集 257

8.2 直接使用正则表达式模块re处理字符串 259

8.3 使用正则表达式对象处理字符串 262

8.4 match对象 264

8.5 精彩案例赏析 267

第9章 数据永久化:文件内容操作 273

9.1 文件操作基本知识 274

9.1.1 内置函数open() 274

9.1.2 文件对象属性与常用方法 276

9.1.3 上下文管理语句with 277

9.2 文本文件内容操作案例精选 277

9.3 二进制文件操作案例精选 282

9.3.1 使用pickle模块读写二进制文件 282

9.3.2 使用struct模块读写二进制文件 284

9.3.3 使用shelve模块操作二进制文件 285

9.3.4 使用marshal模块操作二进制文件 285

9.3.5 其他常见类型二进制文件操作案例 286

第10章 文件与文件夹操作 297

10.1 os模块 297

10.2 os.path模块 300

10.3 shutil模块 301

10.4 其他常用模块 303

10.4.1 glob模块 303

10.4.2 fnmatch模块 303

10.5 精彩案例赏析 304

第11章 代码质量保障:异常处理结构、程序调试与测试 309

11.1 异常处理结构 309

11.1.2 Python内置异常类层次结构 310

11.1.3 异常处理结构 311

11.1.4 断言与上下文管理语句 317

11.2 文档测试doctest 318

11.3 单元测试unittest 320

11.4 覆盖测试 323

11.5 软件性能测试 324

11.6 代码调试 326

11.6.1 使用IDLE调试 326

11.6.2 使用Eclipse+PyDev进行代码调试 329

11.6.3 使用pdb调试 329

第12章 多任务与并行处理:线程、进程、协程、分布式、GPU加速 334

12.1 多线程编程 334

12.1.1 线程概念与标准库threading 335

12.1.2 线程对象 336

12.1.3 线程调度 339

12.1.4 Lock/RLock对象 341

12.1.5 Condition对象 343

12.1.6 Queue对象 345

12.1.7 Event对象 348

12.1.8 Semaphore与BoundedSemaphore 349

12.1.9 Barrier对象 350

12.2 多进程编程 351

12.2.1 进程创建与管理 352

12.2.2 进程同步技术 352

12.2.3 Pool对象 353

12.2.4 Manager对象 358

12.2.5 Listener与Client对象 361

12.2.6 进程间数据交换与共享 362

12.2.7 标准库subprocess 365

12.3 协程 365

12.4 concurrent.futures模块提供的并发执行功能 368

12.5 pySpark并行计算与分布式计算框架 369

12.6 GPU编程 376

12.6.1 使用pycuda实现GPU加速 376

12.6.2 使用pyopencl实现GPU加速 378

12.6.3 使用tensorflow实现GPU加速 379

第13章 互通互联:asyncio提供的网络通信功能 381

13.1 Transport类与Protocol类 381

13.2 StreamReader与StreamWriter 386

附录:精彩在继续 390

附录1:GUI开发 390

附录2:SQLite数据库操作 393

附录3:计算机图形学编程 394

附录4:图像编程 397

附录5:数据分析、机器学习、科学计算可视化 400

附录6:密码学编程 400

附录7:系统运维 401

附录8:Windows系统编程 402

附录9:软件分析与逆向工程 404

责任编辑:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于数独问题的Python实现,我可以给您提供一个基本的算法: 首先,我们需要一个函数来判断某个数字是否可以放在数独的某个位置上,这个函数我们命名为“check()”,实现如下: ```python def check(board, row, col, num): # 判断同一行是否有相同的数字 for i in range(9): if board[row][i] == num: return False # 判断同一列是否有相同的数字 for i in range(9): if board[i][col] == num: return False # 判断同一个3*3的宫格内是否有相同的数字 start_row = (row // 3) * 3 start_col = (col // 3) * 3 for i in range(start_row, start_row + 3): for j in range(start_col, start_col + 3): if board[i][j] == num: return False return True ``` 接下来,我们需要一个递归函数来填充数独,这个函数我们命名为“solve()”,实现如下: ```python def solve(board, row, col): # 如果当前行和列都大于等于9,表示已经填充完毕,返回True if row >= 9 and col >= 9: return True # 如果当前列大于等于9,表示当前行填充完毕,转到下一行 if col >= 9: row += 1 col = 0 # 如果当前位置已经有数字,跳过,转到下一列 if board[row][col] != 0: return solve(board, row, col + 1) # 尝试填充数字1~9 for i in range(1, 10): if check(board, row, col, i): board[row][col] = i # 如果能够成功填充,继续填充下一个位置 if solve(board, row, col + 1): return True # 如果填充失败,回溯,将当前位置的数字清零 board[row][col] = 0 # 如果1~9都不能填充成功,返回False return False ``` 最后,我们需要一个函数来调用“solve()”函数,实现如下: ```python def solveSudoku(board): solve(board, 0, 0) ``` 这样,我们就完成了数独的算法实现。调用“solveSudoku()”函数,传入一个9*9的二维数组即可求解数独
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值