2017-09-15 3 views
1

Detect duplicate in each 3*3 block in a 9*9 matrix数独のように

、複製のための9 * 9マトリックス中に3 * 3行列をPythonのチェックインマイアプローチ: 9つの3×3のブロックに9 * 9を分割するnumpy.vsplitとhsplitを使用し、リストには、私はPythonとnumpyの中にはかなり経験不足だと、私はより多くを賜りますようお願い申し上げ

import numpy as np 
def validSolution(board): 


    b=np.array(board) 
    b=np.vsplit(b,3) 
    for n,ar in enumerate(b): 
     b[n]=np.hsplit(ar,3) 

    for ar in b: 
     for arr in ar: 
      print(len(set(arr.flat))==len(arr.flat)) 

validSolution([[5, 3, 4, 6, 7, 8, 9, 1, 2], 
       [6, 7, 2, 1, 9, 5, 3, 4, 8], 
       [1, 9, 8, 3, 4, 2, 5, 6, 7], 
       [8, 5, 9, 7, 6, 1, 4, 2, 3], 
       [4, 2, 6, 8, 5, 3, 7, 9, 1], 
       [7, 1, 3, 9, 2, 4, 8, 5, 6], 
       [9, 6, 1, 5, 3, 7, 2, 8, 4], 
       [2, 8, 7, 4, 1, 9, 6, 3, 5], 
       [3, 4, 5, 2, 8, 6, 1, 7, 9]]) 

を複製含まれているかどうかをチェックするために)、その後(設定使用し、各3 * 3ブロックを平らにする.flat機能を使用この仕事を効率的に行う方法。

+0

投稿されたソリューションは機能しましたか? – Divakar

+0

はい、ありがとう、ありがとう – lilpig

答えて

3

セットアップ:さんはa9x9グリッドで、bはあなたがaで探している3x3サブ行列(小さいグリッド)であるとしましょう。

手順:形状(3,3,3,3)a4Dは、このように各ウィンドウが第二及び第四の軸に沿って次のようになります。a4Dに再構築されるであろう解決する

  • 一つの方法。

  • 我々は、第1の軸がa4Dから第2の軸とa4Dから4番目と二番目に位置合わせされるよう3Dbを拡張する必要があります。

  • 私たちに4Dのブール配列を与える効率的な、礼儀のNumPy放送である比較を実行します。これらの2つのディムに沿ってすべてのマッチを探し、単に一致するインデックスを取得します。

  • したがって

、実装 -

np.argwhere((a.reshape(3,3,3,3) == b[:,None]).all((1,3))) 

サンプル実行 -

In [190]: a 
Out[190]: 
array([[5, 3, 4, 6, 7, 8, 9, 1, 2], 
     [6, 7, 2, 1, 9, 5, 3, 4, 8], 
     [1, 9, 8, 3, 4, 2, 5, 6, 7], 
     [8, 5, 9, 7, 6, 1, 4, 2, 3], 
     [4, 2, 6, 8, 5, 3, 7, 9, 1], 
     [7, 1, 3, 9, 2, 4, 8, 5, 6], 
     [9, 6, 1, 5, 3, 7, 2, 8, 4], 
     [2, 8, 7, 4, 1, 9, 6, 3, 5], 
     [3, 4, 5, 2, 8, 6, 1, 7, 9]]) 

In [196]: b = a[-3:,-6:-3] # (2,1) grid 

In [197]: b 
Out[197]: 
array([[5, 3, 7], 
     [4, 1, 9], 
     [2, 8, 6]]) 

In [198]: np.argwhere((a.reshape(3,3,3,3) == b[:,None]).all((1,3))) 
Out[198]: array([[2, 1]]) 

In [199]: b = a[:3:,:3] # (0,0) grid 

In [200]: b 
Out[200]: 
array([[5, 3, 4], 
     [6, 7, 2], 
     [1, 9, 8]]) 

In [201]: np.argwhere((a.reshape(3,3,3,3) == b[:,None]).all((1,3))) 
Out[201]: array([[0, 0]]) 

それが何らかの理由で乱雑に見える、あなたがbuilt-insで作業を希望する場合、我々はscikit-imageからview_as_blocksを使用することができ、形状に依存しない解を持つこと -

In [206]: from skimage.util.shape import view_as_blocks 

In [207]: np.argwhere((view_as_blocks(a, b.shape) == b).all((2,3))) 
Out[207]: array([[0, 0]]) 

これらの改造はすべてちょうどviewsであるため、余分なメモリスペースは必要ありません。比較ではaと同じ形状のブール型配列が作成されますが、int/float配列よりもはるかに軽い(Linuxシステムでは8倍軽い)ブール配列であるため、メモリ効率はそれほど悪くありません。

関連する問題