Pyth, 30 29 octets
L?bsmy-tb]dfq1.a-VThbb1y*FUMQ
Essayez-le en ligne: Demonstration / Test Suite
Tous les exemples d'entrées s'exécutent dans le compilateur en ligne. Le dernier prend cependant quelques secondes.
Explication:
Dans mon code, je définirai une fonction récursive y
. La fonction y
prend une liste de coordonnées 2D et renvoie le nombre de pavages de dominos différents en utilisant ces coordonnées. Par exemple y([[0,0], [0,1]]) = 1
(un domino horizontal), y([[0,0], [1,1]]) = 0
(les coordonnées ne sont pas adjacentes) et y([[0,0], [0,1], [1,0], [1,1]]) = 2
(soit deux dominos horizontaux soit deux dominos verticaux). Après avoir défini la fonction, je l'appellerai avec toutes les coordonnées [x,y]
avec x in [0, 1, m-1], y in [0, 1, n-1]
.
Comment fonctionne la fonction récursive? C'est assez simple. Si la liste des accords est vide, il y a exactement un pavage valide et y
retourne 1
.
Sinon, je prends la première coordonnée de la liste b[0]
et recherche les coordonnées restantes pour un voisin. S'il n'y a pas de voisin b[0]
, alors il n'y a pas de mosaïque possible, donc je retourne 0. S'il y a un ou plusieurs voisins, alors le nombre de mosaïques est (le nombre de mosaïques où je me connecte b[0]
avec le premier voisin via une domina, plus le nombre de pavages où je me connecte b[0]
avec le deuxième voisin, plus ...) J'appelle donc la fonction récursivement pour chaque voisin avec la liste raccourcie (en supprimant les deux coords b[0]
et le voisin). Ensuite, je résume tous les résultats et les renvoie.
En raison de l'ordre des coordonnées, il n'y a toujours que deux voisins possibles, celui de droite et celui du dessous. Mais mon algorithme ne s'en soucie pas.
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