import copy
yoko=5
tate=10
kuro=19
#joutai0:黒マスを横nマス(n<yoko)に入れる方法をリストアップ
joutai0 = [[] for i in range(yoko+1)]
joutai0[1].extend([[0],[1]])
temp=[]
for i in range(2,yoko+1):
for j in range(len(joutai0[i-1])):
temp=copy.deepcopy(joutai0[i-1][j])
temp.append(0)
joutai0[i].append(copy.deepcopy(temp))
if temp[-2]==0:
temp[-1]=1
joutai0[i].append(copy.deepcopy(temp))
#joutai1を作る。連なっている黒マスに同じ番号を振る場合の、すべてのパターン
joutai1 = []
def t(original,temp_123,checkichi,shurui):
if checkichi==yoko:
#終了。joutai1に書き込む
joutai1.append(copy.deepcopy(temp_123))
else:
if original[checkichi]==1:
for i in range(1,shurui+2):
temp_123[checkichi]=i
if i==shurui+1:
shurui+=1
t(original,temp_123,checkichi+1,shurui)
else:
t(original,temp_123,checkichi+1,shurui)
for i in range(len(joutai0[yoko])):
original=copy.deepcopy(joutai0[yoko][i])
checkichi=1
shurui=0
temp_123=[0 for i in range(yoko)]
t(original,temp_123,0,0)
#print(joutai1)
print ("joutai1=",len(joutai1))
#joutai2を作る。壁に接続している黒は1とし、他の黒マスの連なりに番号を振る
joutai2=[]
for i in range(len(joutai1)):
joutaimax=max(joutai1[i])
temp=copy.deepcopy(joutai1[i])
joutai2.append(copy.deepcopy(temp))
if joutaimax==0:
continue
if joutaimax==1:
for j in range(len(joutai1[i])):
temp[j]*=2
joutai2.append(copy.deepcopy(temp))
continue
for j in range(len(joutai1[i])):
if temp[j]>0:
temp[j]+=1
joutai2.append(copy.deepcopy(temp))
for j in range(3,joutaimax+2):
temp2=copy.deepcopy(temp)
for k in range(len(joutai1[i])):
if temp2[k]==j:
temp2[k]=1
elif temp2[k]>j:
temp2[k]-=1
joutai2.append(copy.deepcopy(temp2))
#leftwallの場合、左端の黒マスが2以上になることはないので、そのような要素を削除
i=0
while (i<len(joutai2)):
if joutai2[i][0]>1:
# print ("delete",joutai2[i])
joutai2.pop(i)
i-=1
i+=1
#パリティの異なるマスが同じ数(0,1を除く)になることはない
i=0
tyouhuku=int(yoko/2)
while (i<len(joutai2)):
odd=[]
even=[]
j=0
while (j<yoko-1):
odd.append(joutai2[i][j])
j+=1
even.append(joutai2[i][j])
j+=1
if yoko%2==0:
odd.append(joutai2[i][yoko-2])
even.append(joutai2[i][yoko-1])
else:
odd.append(joutai2[i][yoko-1])
check=0
for k in range(2,tyouhuku+1):
if (k in odd)and(k in even):
check=1
if check==1:
joutai2.pop(i)
i-=1
i+=1
#print (joutai2)
print ("joutai2=",len(joutai2))
matrix_seni=[[0 for i in range(len(joutai2))] for j in range(len(joutai2))]
for i in range(len(joutai2)):
for j in range(len(joutai0[yoko])):
#黒マスが縦に並んだらスキップ
if sum([x*y for (x,y) in zip(joutai2[i],joutai0[yoko][j]) ])>0:
continue
temp_above=copy.deepcopy(joutai2[i])
temp_below=copy.deepcopy(joutai0[yoko][j])
nogood=0
#白マス分断が生じたらnogood=1にして、スキップする
k=0
#k=0(左端)のとき
#leftwallの場合、左端の黒マスが2以上になることはない
if temp_below[k]>0:
temp_below[k]=1
ur=temp_above[k+1]
if ur==1:
nogood=1
if ur>1:
for l in range (k+1,yoko):
if temp_above[l]==ur:
temp_above[l]=1
#kが両端でないとき
shurui=max(temp_above)+1
#新たに現れた黒マスで、aboveに連ならないものには、aboveに無い番号を振っていく
for k in range (1,yoko-1):
if temp_below[k]>0:
ul=temp_above[k-1]
ur=temp_above[k+1]
if (ul>0)and(ur>0):
if ul==ur:
nogood=1
elif (ul==1)or(ur==1):
temp_below[k]=1
for l in range (0,yoko):
if (temp_above[l]==ul)or(temp_above[l]==ur):
temp_above[l]=1
if (temp_below[l]==ul)or(temp_below[l]==ur):
temp_below[l]=1
else:
#upperleftに統一
temp_below[k]=ul
for l in range (0,yoko):
if temp_above[l]==ur:
temp_above[l]=ul
if temp_below[l]==ur:
temp_below[l]=ul
elif (ul==0)and(ur==0):
shurui+=1
temp_below[k]=shurui
elif ul*ur==0:
#ul,urの一方のみ0でないとき、その数を入れる
temp_below[k]=ul+ur
if nogood==1:
break
if nogood==1:
nogood=0
continue
k=yoko-1
#k=yoko-1(右端)のとき
if temp_below[k]>0:
if temp_above[k-1]==0:
shurui+=1
temp_below[k]=shurui
else:
temp_below[k]=temp_above[k-1]
#出力する。数字をそろえる
shurui=1
for k in range(yoko):
if temp_below[k]==2 and shurui==0:
shurui=2
if temp_below[k]>1:
if temp_below[k]>shurui:
shurui+=1
temp=temp_below[k]
for l in range(yoko):
if temp_below[l]==temp:
temp_below[l]=shurui
elif temp_below[l]==shurui:
temp_below[l]=temp
#matrix_seniに入力。temp_belowで検索して、該当する位置に1を入れる
jj=0
for k in range(len(joutai2)):
if joutai2[k]==temp_below:
jj=k
break
if k==len(joutai2)-1:
print ("j",joutai2[i])
print ("j",temp_above)
print ("j",temp_below)
print ("")
#この文が表示されてしまう場合、belowがjoutai2の中に存在しない
matrix_seni[i][jj]=1
dp_shurui=len(joutai2)
print ("start")
matrix_kuro=[]
for k in range(dp_shurui):
count=0
for i in range(len(joutai2[k])):
if joutai2[k][i]>0:
count+=1
matrix_kuro.append(count)
matrix_shoki=[]
for k in range(dp_shurui):
if max(joutai2[k])<2:
matrix_shoki.append(1)
else:
matrix_shoki.append(0)
matrix_hyouji=[]
for k in range(dp_shurui):
temp=""
for i in range(len(joutai2[k])):
if joutai2[k][i]==0:
temp+="-"
elif joutai2[k][i]==1:
temp+="X"
else:
temp+=str(joutai2[k][i])
matrix_hyouji.append(temp)
#for i in range(dp_shurui):
# print ("")
# print ("a",joutai2[i])
#
# for j in range(dp_shurui):
# if matrix_seni[i][j]==1:
# print ("b",joutai2[j])
# print(joutai2[k])
# print (temp)
while(tate<15):
dp=[[[0 for i in range(dp_shurui+1)]for j in range(kuro+1)]for k in range(tate+1)]
#現在の行、黒マスの個数、最下列の状態の番号
#1行目
for joutai_new in range (dp_shurui):
if matrix_shoki[joutai_new]==1:
#joutai_newが入るかチェック
kuro_new=matrix_kuro[joutai_new]
dp[1][kuro_new][joutai_new]+=1
for tate_old in range(1,tate):
for joutai_new in range (dp_shurui):
for joutai_old in range (dp_shurui):
if matrix_seni[joutai_old][joutai_new]==1:
#joutai_newが入るかチェック
for kuro_old in range (kuro+1):
if dp[tate_old][kuro_old][joutai_old]>0:
kuro_new=kuro_old+matrix_kuro[joutai_new]
# print(tate_old+1,kuro_new,joutai_new)
dp[tate_old+1][kuro_new][joutai_new]+=dp[tate_old][kuro_old][joutai_old]
printout=0
if printout==1:
#解の一部を表示
for joutai_new in range(dp_shurui):
d=dp[tate][kuro][joutai_new]
if d>0:
tate_comeback=tate
kuro_comeback=kuro
joutai_comeback=joutai_new
print (matrix_hyouji[joutai_comeback])
while (tate_comeback>1):
tate_comeback-=1
kuro_comeback-=matrix_kuro[joutai_comeback]
for joutai_old in range(dp_shurui):
if (matrix_seni[joutai_old][joutai_comeback]==1)and(dp[tate_comeback][kuro_comeback][joutai_old]>0):
print (matrix_hyouji[joutai_old])
break
joutai_comeback=joutai_old
print ("")
kuroall=0
for joutai_new in range(dp_shurui):
d=dp[tate][kuro][joutai_new]
kuroall+=d
if kuroall==0:
tate-=1
kuro-=4
else:
print (kuro, kuroall)
tate+=1
kuro+=3