Pyth, 30 29 bayt
L?bsmy-tb]dfq1.a-VThbb1y*FUMQ
Çevrimiçi deneyin: Gösteri / Test Paketi
Tüm örnek girişler çevrimiçi derleyicide çalışır. Sonuncusu birkaç saniye sürüyor.
Açıklama:
Kodumda özyinelemeli bir işlev tanımlayacağım y
. İşlev y
2B koordinatların bir listesini alır ve bu koordinatları kullanarak farklı domino eğme sayısını döndürür. Örneğin y([[0,0], [0,1]]) = 1
(bir yatay domino), y([[0,0], [1,1]]) = 0
(koordinatlar bitişik değildir) ve y([[0,0], [0,1], [1,0], [1,1]]) = 2
(iki yatay veya iki dikey domino). Fonksiyonunu tanımladıktan sonra tüm koordinatları ile diyeceğiz [x,y]
ile x in [0, 1, m-1], y in [0, 1, n-1]
.
Özyinelemeli işlev nasıl çalışır? Oldukça basit. Koordinatlar listesi boşsa, tam olarak geçerli bir döşeme ve y
geri dönüş vardır 1
.
Aksi takdirde listedeki ilk koordinatı alırım ve b[0]
kalan koordinatları bir komşu için ararım. Komşu b[0]
yoksa, o zaman hiçbir döşeme mümkün değildir, bu nedenle 0'a dönüyorum. Bir veya daha fazla komşu varsa, o zaman tilning sayısı ( b[0]
bir domina aracılığıyla ilk komşuyla bağlandığım tilting sayısı, artı b[0]
ikinci komşu ile bağlandığım tilning sayısı , artı ...) Böylece kısaltılmış listeye sahip her komşu için işlevi iki kez çağırıyorum (iki kord b[0]
ve komşuyu kaldırarak ). Daha sonra tüm sonuçları toplayıp geri veriyorum.
Koordinelerin düzeni nedeniyle her zaman sadece iki komşu vardır, biri sağ tarafta ve aşağıda. Ama algoritmam bunu umursamıyor.
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