Escreva um programa ou função que, dado positivo n e m, calcule o número de inclinações de dominó distintas válidas que você pode ajustar em um retângulo n por m . Essa é a sequência A099390 na Enciclopédia on - line de sequências inteiras . Você pode inserir dados como argumento (s) de função, CLA ou stdin, em qualquer formato razoável. Você deve retornar ou imprimir um único número inteiro como saída.
Cada lado a lado não deve deixar nenhum espaço, e todos os lado a lado são contados, incluindo rotações, reflexões, etc. Por exemplo, as inclinações para 2x3 são:
|-- ||| --|
|-- ||| --|
Exemplos de entradas / saídas:
1, 9 -> 0
2, 2 -> 2
2, 3 -> 3
4, 4 -> 36
4, 6 -> 281
6, 6 -> 6728
7, 10 -> 53175517
Seu programa deve, teoricamente, trabalhar para qualquer n e m , mas se o seu programa requer muita memória ou o seu tipo de dados transborda ele está dispensado. Seu programa deve funcionar corretamente para qualquer n, m <= 8 no entanto.
O menor código em bytes vence.
Respostas:
Pitão,
3029 bytesExperimente on-line: Demonstration / Test Suite
Todas as entradas de exemplo são executadas no compilador online. O último leva alguns segundos.
Explicação:
No meu código, definirei uma função recursiva
y
. A funçãoy
pega uma lista de coordenadas 2D e retorna o número de diferentes inclinação do dominó usando essas coordenadas. Por exemploy([[0,0], [0,1]]) = 1
(um dominó horizontal),y([[0,0], [1,1]]) = 0
(as coordenadas não são adjacentes) ey([[0,0], [0,1], [1,0], [1,1]]) = 2
(dois dominós horizontais ou dois verticais). Depois de definir a função, chamarei com todas as coordenadas[x,y]
comx in [0, 1, m-1], y in [0, 1, n-1]
.Como funciona a função recursiva? É bem simples Se a lista de cordas estiver vazia, haverá exatamente um lado a lado e
y
retornos válidos1
.Caso contrário, pego a primeira coordenada da lista
b[0]
e busco as demais coordenadas por vizinhos. Se não houver vizinhob[0]
, então não será possível colocar lado a lado, portanto, retornarei 0. Se houver um ou mais vizinhos, o número de inclinações será (o número de inclinações em que eu me conectob[0]
com o primeiro vizinho através de uma domina, mais o número de inclinações em que eu me conectob[0]
com o segundo vizinho, mais ...) Então chamo a função recursivamente para cada vizinho com a lista abreviada (removendo as duas cordasb[0]
e o vizinho). Depois, resumi todos os resultados e os devolvo.Por causa da ordem dos cabos, sempre existem apenas dois vizinhos possíveis, o do lado direito e o abaixo. Mas meu algoritmo não se importa com isso.
fonte
Matlab, 292
Estou certo de que isso pode ser muito reduzido, apenas portando-o para outro idioma.
A idéia básica é a brutalidade: criei uma espécie de enumeração de todas as maneiras de como colocar
m*n/2
tijolos de dominó em umam*n
placa. Mas essa enumeração também inclui muitas inclinações inválidas (tijolos que se sobrepõem ou ficam fora do quadro). Portanto, o programa constrói todas essas inclinações e conta apenas as válidas. A complexidade do tempo de execução é sobreO(2^(m*n/2) * m*n)
. A memória não é um problema para o sistema8x8
, pois apenas precisa deO(m*n)
memória. Mas o tempo necessário8x8
é de cerca de 20 dias.Aqui a versão totalmente comentada que explica o que está acontecendo.
PS: Se alguém souber como fazer o destaque da sintaxe do Matlab funcionar, inclua a tag correspondente nesta resposta!
Aqui o totalmente golfe:
fonte
C89, 230 bytes
Para facilitar a leitura, envolvi manualmente esta resposta - todas as novas linhas podem ser removidas com segurança para obter 230 bytes.
Define uma função
int g(int n, int m)
que retorna o número de inclinações. Ele usa uma função auxiliarf
que itera sobre todas as inclinações válidas, colocando um dominó, recorrendo e removendo o dominó em uma placa compartilhada.fonte
Python 243
Optei por uma abordagem de força bruta:
Se todos eles se ajustarem e não houver espaço, teremos uma entrada válida.
Aqui está o código:
fonte