次のアプローチパターンベースを検討するかどうかはわかりませんが、機能し、多くの次元に拡張できると考えられますが、all3
データセットを使用すると、おそらくかなり早い段階で解決されます...
アイデアは、空白のクロスワードから始めることです。
blankCW={{_,_,_},{_,_,_},{_,_,_}};
次に、次の手順を再帰的に実行します。特定のパターンについて、行を順番に確認し、(1つだけ入力して入力した後)一致数が最も少ない行のパターンを展開します。
(* Cache the number of matches for a given pattern *)
nmatch[patt_]:=nmatch[Verbatim@patt]=Length@Cases[all3,patt]
(* A helper to fill single matches if needed *)
fixone[ml_,nl_]:=If[FreeQ[ml[[nl]],Verbatim[_]],ml,
ReplacePart[ml, nl->First@Cases[all3,ml[[nl]]]]];
findCompletions[m_]:=Module[{nn,ur},
(* Pattern w/ filled single matches -> ur, ordering by # of matches -> nn *)
{ur,nn}=NestWhile[{fixone[#[[1]],First@#[[2]]], Rest@#[[2]]}&,
{m,Ordering[nmatch/@m]},
(Length[#[[2]]]>0&&nmatch@#[[1,#[[2,1]]]]==1)&];
(* Expand on the word with the fewest number og matches *)
If[Length[nn]==0,{ur},
With[{n=First@nn},ReplacePart[ur,n-> #]&/@Cases[all3,ur[[n]]]]]];
与えられた候補パターンについて、両方の次元に沿って完成を試して、最も少ないものを維持します。
findCompletionsOriented[m_]:=Module[{osc},
osc=findCompletions/@Union[{m,Transpose@m}];
osc[[First@Ordering[Length/@osc,1]]]]
Unionを使用できるようにするために、最初に再帰幅を実行しますが、より大きな問題には、最初に深さが必要になる場合があります。パフォーマンスはまあまあです:問題の例で116568の一致を見つけるのに8ラップトップ分:
Timing[crosswords=FixedPoint[Union[Join@@(findCompletionsOriented/@#)]&,{blankCW}];]
Length@crosswords
TableForm/@Take[crosswords,5]
Out[83]= {472.909,Null}
Out[84]= 116568
aah aah aah aah aah
Out[86]={ ace ace ace ace ace }
hem hen hep her hes
原則として、これをより高い次元に再帰することが可能である必要があります。つまり、次元3のワードリストの代わりにクロスワードリストを使用します。パターンをリストと照合する時間がリストの長さで線形である場合、これは非常に遅くなります。 100000以上のサイズのワードリスト付き...