importthreading, time, sys, os, copyfrom multiprocessing importProcess, Pool"""# 每一宫分组
a[0-2][0-2] a[0-2][3-5] a[0-2][6-8]
a[3-5][0-2] a[3-5][3-5] a[3-5][6-8]
a[6-8][0-2] a[6-8][3-5] a[6-8][6-8]
# 每一列分组
a[0-8][0] a[0-8][1] a[0-8][2] a[0-8][3] a[0-8][4] a[0-8][5] a[0-8][6] a[0-8][7] a[0-8][08]
# 每一行分组
a[0][0-9]
a[1][0-9]
a[2][0-9]
a[3][0-9]
a[4][0-9]
a[5][0-9]
a[6][0-9]
a[7][0-9]
a[8][0-9]"""
"""中解"""
#a="""904030200#600000048#001004000#400003029#090000010#820600003#000100700#240000001#009070304"""
"""小解"""
#a="""000200049#000007500#001000302#002401090#054309680#080705200#603000900#007500000#490008000"""#"""中解"""#a="""000000010#003024005#520003000#016002470#009070600#072600590#000500027#200380900#060000000"""#"""小解"""#a="""400800270#005200098#300000000#000092086#001000000#620040000#009000004#160005800#053008001"""#"""小解"""
a="""108730000
090000010
024160700
007000005
800501004
500000600
003095870
080000020
000012309"""
"""非常难解(不是好机器不要使用!!!!)"""
#a="""800000000#003600000#070090200#050007000#000045700#000100030#001000068#008500010#090000400"""#''' 解#[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]#'''
#a = """200007000#003400900#040200005#030000040#000631000#080000090#700005010#001004800#000900003"""
#将字符串转换为数组
defstr_list(a):
lis= a.split("\n")
lstt_a=[]for i inlis:#lstt_a.append([int(j) for j in i])
lstt_a.append(list(map(int, i)))returnlstt_a#取一行分组
defqiu_hang(yuanzhi, key):"""a[0][0-9]
a[1][0-9]
a[2][0-9]
a[3][0-9]
a[4][0-9]
a[5][0-9]
a[6][0-9]
a[7][0-9]
a[8][0-9]
:param yuanzhi: 原列表
:param key: 位置参数用到 行‘h'参数
:return: 横向的列表"""h, l=keyreturnyuanzhi[int(h)]#取一列分组
defqiu_lie(yuanzhi, key):"""a[0-8][0] a[0-8][1] a[0-8][2] a[0-8][3] a[0-8][4] a[0-8][5] a[0-8][6] a[0-8][7] a[0-8][08]
:param yuanzhi: 原列表
:param key: 位置参数 用到列‘l’参数
:return: 纵向的列表"""h, l=key
ret_list=[]for i in range(0, 9):
ret_list.append(yuanzhi[int(i)][int(l)])returnret_list#取宫里面的所有元素
defqiu_gong(yuanzhi, key):""":param yuanzhi:原9宫格列表
:param key: 位置参数
:return: 1个宫格列表"""h, l=key
h=int(h)#先判断行数
if h >= 0 and h <= 2:#再取宫格
return list_hang(yuanzhi, l, 0, 3)elif h >= 3 and h <= 5:return list_hang(yuanzhi, l, 3, 6)elif h >= 6 and h <= 8:return list_hang(yuanzhi, l, 6, 9)#宫方式取出所有
deflist_hang(yuanzhi, l, hm, hx):""":param yuanzhi:原列表
:param l: 列信息
:param hm: 最小行值 通过key信息hang确定(固定值)
:param hx: 最大行值 通过key信息hang确定(固定值)
:return: 1个宫格列表"""ret_list=[]
l=int(l)#根据列 ’l‘信息判定列范围,从而确定 是哪一个宫
if l >= 0 and l <= 2:for i inrange(hm, hx):for j in range(0, 3):
ret_list.append(yuanzhi[i][j])elif l >= 3 and l <= 5:for i inrange(hm, hx):for j in range(3, 6):
ret_list.append(yuanzhi[i][j])elif l >= 6 and l <= 8:for i inrange(hm, hx):for j in range(6, 9):
ret_list.append(yuanzhi[i][j])returnret_list#检测可能存在的值
defjiance(yuanzhi, jie):#判断结束
yuanzhi_new =copy.deepcopy(yuanzhi)#第一次求出所有可能解
jie2 =qiu_jie(jie, yuanzhi)#给空白位置赋值
x =chongxinfuzhi(jie2, yuanzhi_new)#x有两种返回值
#一种是返回一个填好的列表,
#一种返回一个元祖,元祖中有(两种解的列表 和 解列表)
#判定是否为一个填好列表,
if len(x) == 9:
flg=if_End(x, jie2)#这个flg 有3种返回值
#False 表示 解还没填写完。
#正确 填写完毕的 列表
#1 表示解 已经空了,相当于全部填写到空位里面去了但是不正确结束线程
ifflg:if flg != 1:print("正确了", os.getpid())
print_shuzu(flg)returnflgelse:print("错误进程结束", os.getpid(), flg)returnflg#如果解还有值递归填写
#jiance(x, jie2)
t = Process(target=jiance, args=(x, jie2))
t.start()else:#拆包两解情况,开启两个进程 分别去处理两种解。
#无限进行递归,
#把所有可能遍历一遍。
#很像一个动图 围棋遍历那个动图,看过的应该知道。。1生2 2生4 4生8 那种 8生16 .....
"""爆炸似增长,非常难解的那个a不是好机器不要去解。很可能电脑卡死
#
#
# #
#
#
#
#
#
# #
#
#
#"""new1, new2, jie2=x#多进程实现
t1 = Process(target=jiance, args=(new1, jie2))
t2= Process(target=jiance, args=(new2, jie2))
t1.start()
t2.start()return
#递归实现 深度过大时会报错,简单解的还可以,难解的不可用
#jie3=copy.deepcopy(jie2)
#jiance(new1, jie2)
#jiance(new2, jie3)
defif_End(new1, jie2):#print("进入判断")
for i injie2:if len(jie2[i]) !=0:returnFalseelse:
fl, i=jiaoyan(new1)iffl:returnnew1else:return 1
#校验
defjiaoyan(yuanzhi_new):
a= "00,13,26,31,44,57,62,75,88"lsit_a= a.split(",")for i inlsit_a:
gong=qiu_gong(yuanzhi_new, i)
hang=qiu_hang(yuanzhi_new, i)
lie=qiu_lie(yuanzhi_new, i)#按照特殊位 'a' 去取出行列宫所有种类的列表去判断。如果去重后长度都为9
if not (len(set(gong)) == 9) or not (len(set(hang)) == 9) or not (len(set(lie)) == 9):returnFalse, i#and 所有位中没有0站位的。就放正确
if 0 in gong or 0 in hang or 0 inlie:returnFalse, ielse:returnTrue, 0#输出数独所有
defprint_shuzu(yuanzhi_new):for i inyuanzhi_new:print(i)#重新赋值
defchongxinfuzhi(jie, yuanzhi_new):
flg=Truefor i injie:#分解解中行列标记{'00': [4, 6, 7, 8, 9], '01': [4, 8, 9], '02': [4, 7, 8], '03': [7, 8, 9], '04': [5, 6, 9], '05': [5, 6, 7, 8, 9], '06': [2, 3, 7, 8], '08': [2, 3, 4, 6, 8, 9], '10': [1, 6, 7, 8, 9], '11': [8, 9], '13': [1, 7, 8, 9], '16': [7, 8], '17': [6, 8], '22': [1, 4, 7, 8], '23': [1, 7, 8, 9], '24': [1, 6, 9], '26': [7, 8], '27': [4, 6, 8], '28': [4, 6, 8, 9], '30': [3, 8], '33': [8, 9], '34': [3, 5, 9], '38': [3, 8], '40': [3, 4, 8], '41': [3, 4, 5, 8], '43': [1, 4, 8], '45': [1, 5, 8], '47': [3, 8], '48': [1, 2, 3, 8], '50': [3, 4, 8], '54': [1, 3, 4], '55': [1, 8], '58': [1, 3, 8], '60': [1, 3, 4, 8, 9], '61': [3, 4, 8, 9], '62': [1, 4, 8], '64': [1, 4, 6, 9], '65': [1, 6, 9], '66': [1, 3, 8], '71': [4, 5], '72': [1, 4, 5, 7], '75': [1, 6, 7], '77': [4, 5, 6], '78': [1, 4, 6], '80': [1, 3, 4, 7, 8, 9], '82': [1, 4, 5, 7, 8], '83': [1, 2, 4, 7, 9], '84': [1, 4, 9], '85': [1, 7, 9], '86': [1, 3, 8], '87': [3, 4, 5, 8], '88': [1, 3, 4, 8]}
h, l =i#h=0,i=0
#这里判断 例如{'00': [4],} 则说明00位置只有一个解 就是 4,则赋值给原列表
if len(jie[i]) == 1:
yuanzhi_new[int(h)][int(l)]=jie[i][0]#如果有解重新赋值到了原列表中则 否定 有多解情况
flg =Falseelse:#判断是否存在一个解的情况
#if flg and 0:
ifflg:#如果都是多种解的情况 是解中没有 可添加的值
returnduogejie(yuanzhi_new, jie)returnyuanzhi_new#固定值--填进去的值#如果是多个解的情况返回两种解的固定值
defduogejie(yuanzhi, jie):#复制两份原列表
yuanzhi_new =copy.deepcopy(yuanzhi)for i injie:
h, l=i#循环‘解’字典,
if len(jie[i]) == 2:
h1, h2=jie[i]print(h1,h2)
yuanzhi_new[int(h)][int(l)]=h1
yuanzhi[int(h)][int(l)]=h2
jie[i].pop()
jie[i].pop()returnyuanzhi_new, yuanzhi, jieelse:returnyuanzhi#求所有可能的解
defqiu_jie(jie, yuanzhi):#print(jie)
for i injie:
gong_lis=qiu_gong(yuanzhi, i)
jie[i]=jiancefangfa(gong_lis, jie[i])
hang_lis=qiu_hang(yuanzhi, i)
jie[i]=jiancefangfa(hang_lis, jie[i])
lie_lis=qiu_lie(yuanzhi, i)
jie[i]=jiancefangfa(lie_lis, jie[i])returnjie#检测是否存在
defjiancefangfa(list_a, wei):#大于0
if len(wei) > 0 and wei[0] == 10:
wei= [i for i in range(1, 10)]
res=[]for i inwei:if i not inlist_a:
res.append(i)returnresdefmain():#字符串转列表
yuanzhi =str_list(a)#解集合
jie =kong_jie(yuanzhi)#正确的值
print(os.getpid())
yuanzhi_new=jiance(yuanzhi, jie)#输出正确的值
ifyuanzhi_new:
print_shuzu(yuanzhi_new)
sys.exit()#初始化空解
defkong_jie(yuanzhi):
jie={}
i=0while i
j=0while j
jie[str(i) + str(j)] = [10]
j+= 1i+= 1
returnjieimportcProfileif __name__ == '__main__':
cProfile.run("main()")