编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需 遵循如下规则 :
- 数字
1-9
在每一行只能出现一次。 - 数字
1-9
在每一列只能出现一次。 - 数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。
空白格用 '.'
表示。
一个数独。
答案被标成红色。
Note:
- 给定的数独序列只包含数字
1-9
和字符'.'
。 - 你可以假设给定的数独只有唯一解。
- 给定数独永远是
9x9
形式的。
def ones(board):
#填唯一值
e=[str(x) for x in range(1,10)]
hhs=[[x for x in e if x not in i] for i in board]
lhs=[[x for x in e if x not in i] for i in [[m[n] for m in board] for n in range(9)]]
ghs=[[x for x in e if x not in sum(i,[])] for i in [[n[p][o-3:o] for p in range(3)] for n in [board[m-3:m] for m in [3,6,9]] for o in [3,6,9]]] while True:
num=0
for i in range(9): for j in range(9): if board[i][j]=='.':
hlghss=[x for x in hhs[i] if x in lhs[j] and x in ghs[3*(i//3)+(j//3)]]
if len(hlghss)==1:
num+=1
board[i][j]=hlghss[0]
hhs[i].remove(hlghss[0])
lhs[j].remove(hlghss[0])
ghs[3*(i//3)+(j//3)].remove(hlghss[0])
if num==0:
hlghs={} for i in range(9): for j in range(9): if board[i][j]=='.':
hlghs[(i,j)]=[x for x in hhs[i] if x in lhs[j] and x in ghs[3*(i//3)+(j//3)]]
break
return hlghs
#填好后返回每个格子的候选值
def onechoice(b,hlg):
#依次填候选值,只填一个,填好测试唯一值,如不能填满则重置board继续填
board=[i.copy() for i in b] for i in hlg: for j in hlg[i]:
board[i[0]][i[1]]=j
if len(ones(board))==0: return i[0],i[1],j
#返回填值信息
board=[i.copy() for i in b]
def twochoice(b,hlg):
#选行列宫互不相等的两格,依次填值,填好测试唯一值,如不能填满则重置board继续填
board=[i.copy() for i in b] for i in hlg: for j in hlg: if i[0]!=j[0] and i[1]!=j[1] and (3*(i[0]//3)+(i[1]//3))!=(3*(j[0]//3)+(j[1]//3)):
for m in hlg[i]: for n in hlg[j]:
board[i[0]][i[1]]=m
board[j[0]][j[1]]=n if len(ones(board))==0: return i[0],i[1],m,j[0],j[1],n
#返回填值信息
board=[i.copy() for i in b]
one=ones(board)
if len(one)!=0:
oc=onechoice(board,one) if oc!=None:
board[oc[0]][oc[1]]=oc[2]
ones(board) else:
tc=twochoice(board,one)
board[tc[0]][tc[1]]=tc[2]
board[tc[3]][tc[4]]=tc[5]
ones(board)
花了一天的时间来做这道题.在递归的地方卡了很久,始终不知道该怎么写,别人的代码给了我一些灵感.感谢!
注意一点:题目中说了数独有唯一解法,所以题目中给的所有数独都可解
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31551894/viewspace-2641862/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/31551894/viewspace-2641862/