Побудова ортогонально-діагональної греко-латинської площі


11

Розглянемо сітку з Nx Nунікальних елементів. Кожен елемент має літеру (від А до Nдругої літери включно) та цифру (від 1 до Nвключно). Отже, кожна пара цифр / літер знаходиться в сітці рівно один раз.

Ваше завдання - влаштувати сітку таким чином:

Кожен рядок, стовпець та діагональ (включаючи обгортання) містять кожну букву та цифру рівно один раз.

Під обгортанням я маю на увазі це

* * * # *
* * # * * 
* # * * *
# * * * *
* * * * #

- це діагональ разом із усіма подібними діагоналями, які потрапляють на краї.

Приклад 5x5сітки:

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

Ваше завдання - написати програму, яка приймає число N, та роздрукувати сітку Nx, Nяк описано вище. Ваша програма повинна працювати для будь-якого 0 < N <= 26. Якщо певна сітка неможлива, слід надрукувати Impossible.

Жорстке кодування відповіді на будь- Nяке заборонено. Програма важко кодується, якщо вона обчислює сітку по-різному (як я судив) для будь-яких N > 26(або якщо вона не вдається обчислити). (Це призначено для запобігання попереднього розрахунку, включаючи попередньо обчислені недійсні сітки або компенсації для заданих сіток).

Це проблема з найшвидшим кодом, і ваш результат - це сума часу, необхідного для запуску вашої програми в усіх можливих Nна моєму комп’ютері. У своїй відповіді, будь ласка, попросіть вашу програму запустити всіх N(тому я маю її встигнути лише один раз). Якщо жодна програма не може обчислити її за 60 секунд, тоді переможець - це відповідь, яка може обчислити сітку з найбільшою Nза 60 секунд. Якщо декілька програм мають однаковий максимум N, то краватка - це найшвидше рішення.

(У мене є пристосована машина Windows 8, і будь-які компілятори чи перекладачі повинні бути у вільному доступі для цього).


Той факт, що ваша машина є Windows, а не Linux, може бути докучаючим для деяких технологій.
orlp

+1 за запитання, але враховуючи, що аналіз вашого прикладу здається досить швидким алгоритмом, мені цікаво, чи дійсно ви зможете виміряти швидкість. Чи можемо ми написати функцію, яка повертає рядок? Тому що я вважаю, що час виклику API для фактичного друку буде довше, ніж обчислювальний.
Річка рівня Св.

@steveverrill так, для тимчасових цілей повернення рядка є прийнятним.
Натан Меррілл

Яке призначення букв і цифр. Чи кожне число відображається біля кожної літери лише один раз, або 1 може бути завжди поряд із A, 2 поруч із B, ...?
Якубе

@Jakube так. Кожен елемент повинен бути унікальним, це означає, що кожна пара чисел / літер у сітці повинна бути унікальною.
Натан Меррілл

Відповіді:


5

Пітон 3

letters = []
numbers = []
for n in range(1,27): 
    if n%2==0 or n%3==0:
        offsets=False
    else:
        offsets = [x for x in range(0,n,2)]
        offsets.extend([x for x in range(1,n,2)])
    letters.append(chr(96+n))
    numbers.append(n)
    if offsets :
        for y in range(n):
            for x in range(n):
                let=letters[(x+offsets[y])%n]
                num=numbers[(offsets[y]-x)%n]
                print (let+str(num), end= "  " if num<10 else " ")
            print("\n")     
    else: 
        print("Impossible\n")

Як це працює?

Наївна реалізація полягала б у тому, щоб проглянути всі можливі розташування літер та цифр у сітці NxN та шукати таку, яка також є Ортогонально-Діагональною Латинською площею (ODLS) (і, таким чином, для деяких потрібно було б пройти все конфігурації та повернення неможливо). Такий алгоритм не відповідав би цьому виклику через абсурдні часові складності. Отже, є три основні спрощення та виправдання (часткові докази та розуміння того, чому це працює) для конструкцій ODLS, які використовуються в моїй реалізації:

Перший - це поняття про те, що нам потрібно створити лише дійсну Діагональну латинську площу (сітка NxN, така що кожен рядок, стовпець, загорнута діагональ містить один елемент набору з N різних елементів рівно один раз) перших N літер алфавіту. Якщо ми можемо побудувати такий діагональний латинський квадрат (DLS), то ODLS може бути побудований за допомогою DLS з відповідним обміном елементів і гортанням. Виправдання:

Let us first look at an example using the example grid
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
Every ODLS can be separated into two DLS (by definition), so
we can separate the grid above into two DLS, one containing letters, the other - numbers
a b c d e
c d e a b
e a b c d
b c d e a
d e a b c
and
1 2 3 4 5 
4 5 1 2 3
2 3 4 5 1
5 1 2 3 4 
3 4 5 1 2
If we transform the number DLS by the mapping 1-->e, 2-->d, 3-->c, 4-->b, 5-->a,
1 2 3 4 5 --> e d c b a
4 5 1 2 3 --> b a e d c
2 3 4 5 1 --> d c b a e
5 1 2 3 4 --> a e d c b
3 4 5 1 2 --> c b a e d
Now if we put the transformed number grid next to the original letter grid,
Original  | Transformed
a b c d e | e d c b a
c d e a b | b a e d c
e a b c d | d c b a e
b c d e a | a e d c b
d e a b c | c b a e d
It can be clearly seen that the number grid is a horizontal flip of
the letter grid withminor letter to number substitutions.
Now this works because flipping guarantees that no two pairs occur more than once,
and each DLS  satisfies the requirements of the ODLS.

Друге спрощення - це поняття, що якщо ми знайшли відповідну конфігурацію (SC) одного елемента (сітка NxN така, що кожен рядок, стовпець, загорнута діагональ містить цей елемент рівно один раз), то DLS може бути побудований заміною елемента і зміщення СК. Виправдання:

If "_" is an empty space and "a" the element then a valid SC of a 7x7 grid is
a _ _ _ _ _ _
_ _ a _ _ _ _
_ _ _ _ a _ _
_ _ _ _ _ _ a
_ a _ _ _ _ _ 
_ _ _ a _ _ _
_ _ _ _ _ a _
or
a _ _ _ _ _ _
_ _ _ a _ _ _
_ _ _ _ _ _ a
_ _ a _ _ _ _
_ _ _ _ _ a _ 
_ a _ _ _ _ _
_ _ _ _ a _ _
(the second one can actually be obtained from the first one via rotation)
now say we took the second SC, shifted it one unit to the right and 
replaced all "a" with "b"
a _ _ _ _ _ _       _ a _ _ _ _ _       _ b _ _ _ _ _
_ _ _ a _ _ _       _ _ _ _ a _ _       _ _ _ _ b _ _
_ _ _ _ _ _ a       a _ _ _ _ _ _       b _ _ _ _ _ _
_ _ a _ _ _ _  -->  _ _ _ a _ _ _  -->  _ _ _ b _ _ _
_ _ _ _ _ a _       _ _ _ _ _ _ a       _ _ _ _ _ _ b
_ a _ _ _ _ _       _ _ a _ _ _ _       _ _ b _ _ _ _
_ _ _ _ a _ _       _ _ _ _ _ a _       _ _ _ _ _ b _
Now if we overlaid the SC of "a" with the SC of "b" we get
a b _ _ _ _ _
_ _ _ a b _ _
b _ _ _ _ _ a
_ _ a b _ _ _
_ _ _ _ _ a b 
_ a b _ _ _ _
_ _ _ _ a b _
If we repeated these steps for the other five letters, we would arrive at a DLS
a b c d e f g
e f g a b c d
b c d e f g a
f g a b c d e
c d e f g a b 
g a b c d e f
d e f g a b c
This is a DLS, since each SC follows the general requirements of a DLS 
and shifting ensured that each element has its own cell.
Another thing to note is that each row contains the string "abcdefg" that is offset 
by some cells. This leads to another simplification: we only need to find the 
offsets of the string in every row and we are finished.

Останнє спрощення полягає в наступному - всі DLS простих N, крім N = 2 або N = 3, можуть бути побудовані, і якщо N можна розбити на два числа, відповідні DLS можуть бути побудовані, то DLS цього N може будуватися. Я здогадуюсь, що зворотне також має місце. (Іншими словами, ми можемо побудувати лише DLS для N, який не ділиться на 2 або 3)

Pretty obvious why 2x2 or 3x3 cant be made. For any other prime this can be done
by assigning a each consecutive row a shift that is by two bigger than the previous, 
for N=5 and N=7 this looks like (with elements other than "a" ommited)
N=5
a _ _ _ _ offset = 0
_ _ a _ _ offset = 2
_ _ _ _ a offset = 4
_ a _ _ _ offset = 6 = 1 (mod 5)
_ _ _ a _ offset = 8 = 3 (mod 5)
N=7
a _ _ _ _ _ _ offset = 0
_ _ a _ _ _ _ offset = 2
_ _ _ _ a _ _ offset = 4
_ _ _ _ _ _ a offset = 6
_ a _ _ _ _ _ offset = 8 = 1 (mod 7)
_ _ _ a _ _ _ offset = 10 = 3 (mod 7)
_ _ _ _ _ a _ offset = 12 = 5 (mod 7
(Why this works on all prime N (actually all N that are not divisible
by 3 or 2) can probably be proven via some kind of induction but i will
omit that, this is just what my code uses and it works)
Now, the first composite number that is not
divisible by 2 or 3 is 25 (it also occurs in the range our program must test)
Let A denote the DLS of N = 5
a b c d e 
d e a b c 
b c d e a 
e a b c d 
c d e a b
Let F be the DLS A where each letter is substituted by the letter five postions after it 
a-->f, b-->g etc. So F is 
f g h i j 
j e f g h 
g h i j f 
j f g h i 
h i j f g
Let K be the DLS a where each letter is substituted by the letter ten postions after it
a-->k, b--> l etc.
Let P be defined likewise (so a-->p, b-->q etc)
Let U be defined likewise (so a-->u, b-->v etc)
Now, since the DLS A could be constructed, then by substituting a --> A, b--> F etc.
we get a DLS of N=5*5 (A has five rows and five columns and each is filled with a 
grid of five rows and five columns)
A F K P U
P U A F K
F K P U A
U A F K P
K P U A F
Now since smaller DLS in the big DLS satisfies the 
conditions of a DLS and the big one also satisfies the DLS conditions,
then the resulting grid is also a DLS 

введіть тут код

Зображення того, що я мав на увазі з меншими - більшими DLS

Now this kind of thing works for all constructible N and can be proven similiarly.

I have a strong sense that the converse (if some N isnt constructible
(2 and 3) then no multiple of that N is constructible) is also true but have a hard time 
proving it (test data up to N=30 (took a veeery long time to calculate) confirm it though)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.