ネットで見つけた計算ブロックの問題をPythonで解いてみました。(^_^;
ルールの概要は次の通りです。前回は和でしたが、今回は積と商を使います。
①1〜9までの数字…(ry
②太線で囲まれたブロック内のマスが2つのとき、ブロック内に書かれた数字はマスに入る数字の積または商を表す。
③太線で囲まれたブロック内のマスが3つ以上のとき、ブロック内に書かれた数字はマスに入る数字の積を表す。
0 1 2 3 4 5 6 7 8 +---+---+---+---+---+---+---+---+---+ 0 |72 |50 |28 |54 |2 |24 | +---+---+---+ + +---+ + + + 1 |294 | | |72 | | | | +---+ +---+---+---+ +---+---+ + 2 |576| |42 |15 | |4 | | + +---+ +---+---+---+---+---+ + 3 | | |24 |10 | | +---+---+---+---+---+---+---+---+---+ 4 |24 |2 |432 |12 |35 | + + +---+---+---+---+---+---+---+ 5 | | |252 |30 |432 | + +---+---+---+---+---+ + +---+ 6 | |48 |3 |35 | | |63 | +---+---+---+---+ + +---+---+ + 7 |120 | | |4 | | +---+---+---+---+---+---+---+---+---+ 8 |20 |3 |3 |56 | +---+---+---+---+---+---+---+---+---+
ただし、外側の数字は、プログラム用の配列のインデックスです。
今回は、さすがに「Perm = [list(itertools.permutations(R))]*8」で回すのは大変なので、各ループを必要条件で絞り込んでみました。例えば、上の[0][3]の位置に入る数は、50の約数である必要があります。
よって、これを用いて、プログラム中の「if 50%p[3]!=0: continue」のようにして、Perm[0]の候補を絞り込みました。
ちなみに、このブロックは、縦横違う数字という条件より、m[0][3]=5,m[1][3]=2,m[1][2]=5と決定するのですが、そこまでは使いませんでした。(^_^;
この他にも、3つのマスからなるL型および逆L型のもので、ブロック内に書かれた数字が2,3,294,576などのものも決定することができます。こういうのも使うと、もう少し速くなります。(^_^;
● CalcBlocks2.py
# coding: UTF-8 # CalcBlocks2.py from time import time import itertools def toStr(lst): return '[%s]'%','.join(['%s'%x for x in lst]) # 列がダブっていないか調べる def isDuplicated(n,li2D): m = len(li2D) for i in range(m): li = [li2D[j][i] for j in range(n)] if len(set(li))!=n: return True return False def chk2Cells(a,b,c): if a*b==c: return True l,s = max(a,b),min(a,b) return l%s==0 and l//s==c def main(): tm = time() # Timer Start m = [[0]*9]*9 R = range(1,10) ## Perm = [list(itertools.permutations(R))]*8 Perm = [[],[],[],[],[],[],[],[]] for p in itertools.permutations(R): # Perm[0] if p[0]*p[1]*p[2]!= 72: continue if 50%p[3]!=0: continue if 28%p[4]!=0: continue if 54%(p[5]*p[6])!=0: continue if 24%p[8]!=0: continue Perm[0].append(p) for p in itertools.permutations(R): # Perm[1] if 294%(p[0]*p[1])!=0: continue if 50%(p[2]*p[3])!=0: continue if 28%p[4]!=0: continue if 72%p[5]!=0: continue if 54%p[6]!=0: continue if 24%p[8]!=0: continue Perm[1].append(p) for p in itertools.permutations(R): # Perm[2] if 576%p[0]!=0: continue if 294%p[1]!=0: continue if 42%p[2]!=0: continue if p[3]*p[4]!=15: continue if 72%p[5]!=0: continue if 24%p[8]!=0: continue Perm[2].append(p) for p in itertools.permutations(R): # Perm[3] if 576%(p[0]*p[1])!=0: continue if 42%p[2]!=0: continue if p[3]*p[4]!=24: continue if p[5]*p[6]*p[7]!=10: continue if 24%p[8]!=0: continue Perm[3].append(p) for p in itertools.permutations(R): # Perm[4] if 24%p[0]!=0: continue if 2%p[1]!=0: continue if p[2]*p[3]*p[4]!=432: continue if p[5]*p[6]!=12: continue if p[7]*p[8]!=35: continue Perm[4].append(p) for p in itertools.permutations(R): # Perm[5] if 24%p[0]!=0: continue if 2%(p[1]*p[2])!=0: continue if p[3]*p[4]*p[5]!=252: continue if 30%p[6]!=0: continue if 432%(p[7]*p[8])!=0: continue Perm[5].append(p) for p in itertools.permutations(R): # Perm[6] if 24%p[0]!=0: continue if p[1]*p[2]*p[3]!=48: continue if 3%p[4]!=0: continue if 35%p[5]!=0: continue if 30%p[6]!=0: continue if 432%p[7]!=0: continue if 63%p[8]!=0: continue Perm[6].append(p) for p in itertools.permutations(R): # Perm[7] if p[0]*p[1]*p[2]!=120: continue if 3%(p[3]*p[4])!=0: continue if 35%p[5]!=0: continue if 63%p[8]!=0: continue Perm[7].append(p) ## for n in range(8): print(len(Perm[n])) ## exit() for m[0] in Perm[0]: ## if m[0][0]*m[0][1]*m[0][2]!= 72: continue for m[1] in Perm[1]: if m[0][3]*m[1][2]*m[1][3]!= 50: continue if m[0][4]*m[1][4]!= 28: continue if m[0][5]*m[0][6]*m[1][6]!= 54: continue if not chk2Cells(m[0][7],m[1][7],2): continue if isDuplicated(2,m): continue for m[2] in Perm[2]: if m[1][0]*m[1][1]*m[2][1]!=294: continue ## if m[2][3]*m[2][4]!= 15: continue if m[1][5]*m[2][5]!= 72: continue if not chk2Cells(m[2][6],m[2][7],4): continue if isDuplicated(3,m): continue for m[3] in Perm[3]: if m[2][0]*m[3][0]*m[3][1]!=576: continue if m[2][2]*m[3][2]!= 42: continue ## if m[3][3]*m[3][4]!= 24: continue ## if m[3][5]*m[3][6]*m[3][7]!= 10: continue if m[0][8]*m[1][8]*m[2][8]*m[3][8]!= 24: continue if isDuplicated(4,m): continue for m[4] in Perm[4]: ## if m[4][2]*m[4][3]*m[4][4]!=432: continue ## if m[4][5]*m[4][6]!= 12: continue ## if m[4][7]*m[4][8]!= 35: continue if isDuplicated(5,m): continue for m[5] in Perm[5]: if m[4][1]*m[5][1]*m[5][2]!= 2: continue ## if m[5][3]*m[5][4]*m[5][5]!=252: continue if isDuplicated(6,m): continue for m[6] in Perm[6]: if m[4][0]*m[5][0]*m[6][0]!= 24: continue ## if m[6][1]*m[6][2]*m[6][3]!= 48: continue if m[5][6]*m[6][6]!= 30: continue if m[5][7]*m[5][8]*m[6][7]!=432: continue if isDuplicated(7,m): continue for m[7] in Perm[7]: ## if m[7][0]*m[7][1]*m[7][2]!=120: continue if m[6][4]*m[7][3]*m[7][4]!= 3: continue if m[6][5]*m[7][5]!= 35: continue if m[6][8]*m[7][8]!= 63: continue if not chk2Cells(m[7][6],m[7][7],4): continue if isDuplicated(8,m): continue for i in range(9): li = [m[j][i] for j in range(8)] m[8][i] = 45-sum(li) if m[8][0]*m[8][1]!= 20: continue if m[8][6]*m[8][7]*m[8][8]!= 56: continue if not chk2Cells(m[8][2],m[8][3],3): continue if not chk2Cells(m[8][4],m[8][5],3): continue # チェックを潜り抜けたものだけを表示 for n in range(9): print(toStr(m[n])) print("Runtime : %.3f [sec]"%(time()-tm)) # Timer Stop & Disp if __name__ == '__main__': main()
●実行結果
[1,9,8,5,7,2,3,6,4] [7,6,5,2,4,8,9,3,1] [8,7,6,3,5,9,1,4,2] [9,8,7,4,6,1,2,5,3] [2,1,9,6,8,3,4,7,5] [3,2,1,7,9,4,5,8,6] [4,3,2,8,1,5,6,9,7] [6,5,4,1,3,7,8,2,9] [5,4,3,9,2,6,7,1,8] Runtime : 2.125 [sec]
※参考URL
●判断推理のダンスのペアの問題をPythonで解いてみた。
●計算ブロックの問題をPythonで解いてみた。
- 作者: 宮本哲也
- 出版社/メーカー: 学研プラス
- 発売日: 2006/11/14
- メディア: 単行本
- 購入: 1人 クリック: 1回
- この商品を含むブログ (4件) を見る