Pyth, 30 29 bajtów
L?bsmy-tb]dfq1.a-VThbb1y*FUMQ
Wypróbuj online: pakiet demonstracyjny / testowy
Wszystkie przykładowe dane wejściowe działają w kompilatorze online. Ostatni trwa jednak kilka sekund.
Wyjaśnienie:
W moim kodzie zdefiniuję funkcję rekurencyjną y
. Funkcja y
pobiera listę współrzędnych 2D i zwraca liczbę różnych nachyleń domina przy użyciu tych współrzędnych. Np. y([[0,0], [0,1]]) = 1
(Jedno domino poziome), y([[0,0], [1,1]]) = 0
(współrzędne nie sąsiadują) i y([[0,0], [0,1], [1,0], [1,1]]) = 2
(dwa domino poziome lub dwa pionowe). Po zdefiniowaniu funkcji Zadzwonię go z wszystkich współrzędnych [x,y]
z x in [0, 1, m-1], y in [0, 1, n-1]
.
Jak działa funkcja rekurencyjna? To całkiem proste. Jeśli lista współrzędnych jest pusta, istnieje dokładnie jeden poprawny kafelek i y
zwraca 1
.
W przeciwnym razie biorę pierwszą współrzędną z listy b[0]
i szukam pozostałych współrzędnych w poszukiwaniu sąsiadów. Jeśli nie ma sąsiada b[0]
, to nie jest możliwe kafelkowanie, dlatego zwracam 0. Jeśli jest jeden lub więcej sąsiadów, liczba tilowań to (liczba tilings, w których łączę się b[0]
z pierwszym sąsiadem za pośrednictwem domeny, plus liczba przechyleń, w których łączę się b[0]
z drugim sąsiadem, plus ...) Więc wywołuję funkcję rekurencyjnie dla każdego sąsiada ze skróconą listą (poprzez usunięcie dwóch współrzędnych b[0]
i sąsiada). Następnie sumuję wszystkie wyniki i zwracam je.
Ze względu na kolejność strun możliwe są zawsze tylko dwa sąsiedzi, ten po prawej stronie i ten poniżej. Ale mój algorytm się tym nie przejmuje.
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