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