Napisz program lub funkcję, która podając dodatnią wartość n i m oblicza liczbę prawidłowych odrębnych nachyleń domina, które można zmieścić w prostokącie n na m . Jest to sekwencja A099390 w Online Encyclopedia of Integer Sequences . Możesz przyjmować dane wejściowe w postaci argumentów funkcji, CLA lub standardowego wejścia, w dowolnym rozsądnym formacie. Musisz zwrócić lub wydrukować jedną liczbę całkowitą jako wynik.
Każde kafelkowanie nie może pozostawiać żadnych przerw, a każdy odrębny kafelek jest liczony, w tym obroty, odbicia itp. Na przykład, kafelki dla 2x3 to:
|-- ||| --|
|-- ||| --|
Przykładowe wejścia / wyjścia:
1, 9 -> 0
2, 2 -> 2
2, 3 -> 3
4, 4 -> 36
4, 6 -> 281
6, 6 -> 6728
7, 10 -> 53175517
Twój program powinien teoretycznie działać dla każdego n i m , ale jeśli program wymaga zbyt dużo pamięci lub twój typ danych przelewa to usprawiedliwiona. Twój program musi jednak działać poprawnie dla dowolnego n, m <= 8.
Najkrótszy kod w bajtach wygrywa.
Odpowiedzi:
Pyth,
3029 bajtówWypró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
. Funkcjay
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ą) iy([[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]
zx 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
zwraca1
.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ąsiadab[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ędnychb[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.
źródło
Matlab, 292
Jestem pewien, że można to znacznie skrócić, przenosząc go na inny język.
Podstawową ideą jest brutalne: wymyśliłem rodzaj wyliczenia wszystkich sposobów umieszczania
m*n/2
cegieł domina nam*n
planszy. Ale to wyliczenie obejmuje również wiele nieprawidłowych przechyłów (cegieł, które nakładają się lub wychodzą poza planszę). Program konstruuje wszystkie przechyłki i liczy tylko te prawidłowe. Chodzi o złożoność środowiska wykonawczegoO(2^(m*n/2) * m*n)
. Pamięć nie stanowi problemu,8x8
ponieważ potrzebuje tylkoO(m*n)
pamięci. Ale potrzebny czas8x8
to około 20 dni.Oto w pełni skomentowana wersja, która wyjaśnia, co się dzieje.
PS: Jeśli ktoś wie, jak sprawić, by wyróżnianie składni Matlaba działało, prosimy o dołączenie odpowiedniego znacznika w tej odpowiedzi!
Oto w pełni golfowy:
źródło
C89, 230 bajtów
Dla czytelności odłożyłem ręcznie tę odpowiedź - wszystkie znaki nowej linii można bezpiecznie usunąć, aby dostać się do 230 bajtów.
Definiuje funkcję
int g(int n, int m)
zwracającą liczbę przechyleń. Wykorzystuje funkcję pomocniczą,f
która iteruje wszystkie prawidłowe przechylenia, umieszczając jedno domino, rekursywnie, a następnie usuwając domino ze wspólnej tablicy.źródło
Python 243
Zdecydowałem się na brutalne podejście:
Jeśli wszystkie pasują i nie ma już wolnych miejsc, mamy prawidłowy wpis.
Oto kod:
źródło