Escribir un programa o función que dado positivo n y m calcula el número de mosaicos dominó distintas válidas que puede caber en un n por m rectángulo. Esta es la secuencia A099390 en la Enciclopedia en línea de secuencias enteras . Puede tomar la entrada como argumento (s) de función, CLA o en stdin, en cualquier formato razonable. Debe devolver o imprimir un entero entero como salida.
Cada mosaico no debe dejar espacios, y se cuenta cada mosaico distinto, incluidas las rotaciones, reflexiones, etc. Por ejemplo, las inclinaciones para 2x3 son:
|-- ||| --|
|-- ||| --|
Ejemplo de entradas / salidas:
1, 9 -> 0
2, 2 -> 2
2, 3 -> 3
4, 4 -> 36
4, 6 -> 281
6, 6 -> 6728
7, 10 -> 53175517
Su programa debe trabajar en teoría, para cualquier n y m , pero si su programa requiere demasiada memoria o el tipo de datos se desborda excusado. Sin embargo, su programa debe funcionar correctamente para cualquier n, m <= 8.
El código más corto en bytes gana.
Respuestas:
Pyth,
3029 bytesPruébelo en línea: Demonstration / Test Suite
Todas las entradas de ejemplo se ejecutan en el compilador en línea. Sin embargo, el último tarda unos segundos.
Explicación:
En mi código definiré una función recursiva
y
. La funcióny
toma una lista de coordenadas 2D y devuelve el número de diferentes inclinaciones de dominó utilizando estas coordenadas. Por ejemploy([[0,0], [0,1]]) = 1
(un dominó horizontal),y([[0,0], [1,1]]) = 0
(las coordenadas no son adyacentes) yy([[0,0], [0,1], [1,0], [1,1]]) = 2
(dos dominós horizontales o dos verticales). Después de definir la función, la llamaré con todas las coordenadas[x,y]
conx in [0, 1, m-1], y in [0, 1, n-1]
.¿Cómo funciona la función recursiva? Es bastante simple. Si la lista de coordenadas está vacía, hay exactamente un mosaico válido y
y
retornos1
.De lo contrario, tomo la primera coordenada de la lista
b[0]
y busco las coordenadas restantes para un vecino. Si no hay ningún vecinob[0]
, entonces no es posible el mosaico, por lo tanto, devuelvo 0. Si hay uno o más vecinos, entonces el número de inclinaciones es (el número de inclinaciones donde me conectob[0]
con el primer vecino a través de una domina, más el número de inclinaciones donde me conectob[0]
con el segundo vecino, más ...) Entonces llamo a la función de forma recursiva para cada vecino con la lista acortada (eliminando las dos coordenadasb[0]
y el vecino). Después, resumo todos los resultados y los devuelvo.Debido al orden de los cables, siempre hay dos vecinos posibles, el del lado derecho y el de abajo. Pero mi algoritmo no se preocupa por eso.
fuente
Matlab, 292
Estoy seguro de que esto se puede acortar mucho simplemente portándolo a otro idioma.
La idea básica es la fuerza bruta: se me ocurrió una especie de enumeración de todas las formas de colocar
m*n/2
ladrillos de dominó en unm*n
tablero. Pero esta enumeración también incluye muchas inclinaciones no válidas (ladrillos que se superponen o salen del tablero). Por lo tanto, el programa construye todas esas inclinaciones y solo cuenta las válidas. Se trata de la complejidad del tiempo de ejecuciónO(2^(m*n/2) * m*n)
. La memoria no es un problema8x8
ya que solo necesitaO(m*n)
memoria. Pero el tiempo necesario8x8
es de unos 20 días.Aquí la versión completamente comentada que explica lo que está sucediendo.
PD: Si alguien sabe cómo hacer que el resaltado de sintaxis de Matlab funcione, ¡incluya la etiqueta correspondiente en esta respuesta!
Aquí el totalmente golfizado:
fuente
C89, 230 bytes
Para facilitar la lectura, escribí esta respuesta a mano: todas las líneas nuevas se pueden eliminar de forma segura para llegar a 230 bytes.
Define una función
int g(int n, int m)
que devuelve el número de inclinaciones. Utiliza una función auxiliarf
que itera sobre todas las inclinaciones válidas colocando un dominó, recurriendo y luego eliminando el dominó en un tablero compartido.fuente
Python 243
Opté por un enfoque de fuerza bruta:
Si todos encajan y no quedan espacios, tenemos una entrada válida.
Aquí está el código:
fuente