Rozważ siatkę N
x N
unikalnych elementów. Każdy element ma literę (od A do N
th, włącznie) i liczbę (od 1 do N
włącznie). Dlatego każda para cyfr / liter znajduje się w siatce dokładnie raz.
Twoim zadaniem jest takie ułożenie siatki, aby:
Każdy rząd, kolumna i przekątna (w tym zawijanie) zawiera dokładnie jedną literę i cyfrę.
Mówiąc o opakowaniu, mam na myśli to
* * * # *
* * # * *
* # * * *
# * * * *
* * * * #
jest przekątną, wraz ze wszystkimi podobnymi przekątnymi, które uderzają o krawędzie.
Przykładowa 5x5
siatka to:
A1 B2 C3 D4 E5
C4 D5 E1 A2 B3
E2 A3 B4 C5 D1
B5 C1 D2 E3 A4
D3 E4 A5 B1 C2
Twoim zadaniem jest napisanie programu, który akceptuje liczbę N
, i wydrukowanie siatki N
x N
zgodnie z powyższym opisem. Twój program powinien działać dla każdego 0 < N <= 26
. Jeśli określona siatka nie jest możliwa, należy wydrukować Impossible
.
Twarde kodowanie odpowiedzi na dowolne N
jest niedozwolone. Program jest zakodowany na stałe, jeśli oblicza siatkę w inny sposób (według mnie) dla dowolnego N > 26
(lub jeśli nie oblicza). (Ma to na celu zapobieganie wstępnemu obliczeniu, w tym wstępnie obliczonym nieprawidłowym siatkom lub przesunięciom dla danych siatek).
Jest to problem z najszybszym kodem, a twój wynik to suma czasu potrzebnego do uruchomienia twojego programu na wszystkich możliwych N
komputerach. W odpowiedzi proszę o uruchomienie całego programu N
(więc muszę go tylko raz ustalić). Jeśli żaden program nie jest w stanie go obliczyć w czasie krótszym niż 60 sekund, zwycięzca jest odpowiedzią, która może obliczyć tabelę z największą N
w 60 sekund. Jeśli wiele programów ma takie same maksimum N
, rozstrzygnięcie jest najszybszym rozwiązaniem.
(Mam przyzwoicie zasilaną maszynę z Windows 8 i wszelkie potrzebne kompilatory lub tłumacze muszą być dla niej swobodnie dostępne).
źródło
Odpowiedzi:
Python 3
Jak to działa?
Naiwną implementacją byłoby przejrzenie wszystkich możliwych układów liter i cyfr w siatce NxN i poszukiwanie takiego, który jest również prostopadłościennym przekątnym łacińskim kwadratem (ODLS) (a zatem dla niektórych musiałby po prostu przejść przez wszystkie konfiguracje i zwrot niemożliwe). Taki algorytm nie pasowałby do tego wyzwania z powodu absurdalnej złożoności czasu. Istnieją więc trzy główne uproszczenia i uzasadnienia (częściowe dowody i spostrzeżenia, dlaczego to działa) konstrukcji ODLS zastosowanych w mojej implementacji:
Pierwszym jest założenie, że wystarczy wygenerować prawidłowy przekątny łaciński kwadrat (siatka NxN taka, że każdy wiersz, kolumna, zawinięta diagonalnie zawiera każdy element zbioru N odrębnych elementów dokładnie raz) pierwszych N liter alfabet. Jeśli możemy zbudować taki przekątny kwadrat łaciński (DLS), wówczas można zbudować ODLS za pomocą DLS z odpowiednią wymianą elementów i przerzucaniem. Usprawiedliwienie:
Drugim uproszczeniem jest założenie, że jeśli znaleźliśmy odpowiednią konfigurację (SC) jednego elementu (siatka NxN, tak że każdy rząd, kolumna, zawinięta diagonalnie zawiera ten element dokładnie jeden raz), wówczas można zbudować DLS poprzez zastąpienie elementu i przesunięcie SC. Usprawiedliwienie:
Ostatnie uproszczenie jest następujące - wszystkie DLS pierwszej N, z wyjątkiem N = 2 lub N = 3, mogą być skonstruowane, a jeśli N może być podzielony na dwie liczby, których odpowiedni DLS może być skonstruowany, to DLS tej N może być zbudowanym. Przypuszczam, że tak samo jest w przypadku rozmowy. (Innymi słowy, możemy zbudować DLS tylko dla N, którego nie można podzielić przez 2 lub 3)
Obraz tego, co miałem na myśli z mniejszym - większym DLS
źródło