Pyth、30 29バイト
L?bsmy-tb]dfq1.a-VThbb1y*FUMQ
オンラインで試す:デモ / テストスイート
すべての入力例は、オンラインコンパイラで実行されます。最後のものは数秒かかります。
説明:
私のコードでは、再帰関数を定義しますy
。この関数y
は2D座標のリストを取り、これらの座標を使用してさまざまなドミノタイルの数を返します。たとえば、y([[0,0], [0,1]]) = 1
(1つの水平ドミノ)、y([[0,0], [1,1]]) = 0
(座標が隣接していない)、y([[0,0], [0,1], [1,0], [1,1]]) = 2
(2つの水平ドミノまたは2つの垂直ドミノ)。関数を定義した後、すべての座標で[x,y]
を呼び出しますx in [0, 1, m-1], y in [0, 1, n-1]
。
再帰関数はどのように機能しますか?とても簡単です。coordsのリストが空の場合、有効なタイリングは1つだけあり、をy
返します1
。
それ以外の場合は、リストの最初の座標を取得しb[0]
、残りの座標から近傍を検索します。へのネイバーがない場合b[0]
、タイリングは不可能であるため、0を返します。1つ以上のネイバーがある場合、タイリングの数は(b[0]
ドミナを介して最初のネイバーと接続するタイリングの数に加えて、b[0]
2番目のネイバーに接続するタイリングの数に加えて...)したがって、(2つの座標b[0]
とネイバーを削除することにより)短縮されたリストを使用して、ネイバーごとに関数を再帰的に呼び出します。その後、すべての結果を集計して返します。
座標の順序のため、可能な隣人は常に2つしかありません。1つは右側にあり、もう1つは下にあります。しかし、私のアルゴリズムはそれを気にしません。
UMQ convert the input numbers into ranges
*F Cartesian product (coords of each square)
L define a function y(b):
?b if len(b) > 0:
f b filter b for squares T, which satisfy:
.a-VThb Euclidean distance between T and b[0]
q1 is equal to 1 (direct neighbors)
m map each neighbor d to:
-tb]d remove d from b[1]
y and call recursively y with the rest
s sum all those values and return them
else:
1 return 1 (valid domino tiling found)
y*FUMQ Call y with all coords and print the result