파이썬 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 구조에 대한 세 가지 주요 단순화 및 타당성 (작동 이유에 대한 부분 증거 및 통찰력)이 있습니다.
첫 번째는 첫 번째 N 문자의 유효한 대각선 라틴 정사각형 (각 행, 열, 랩핑 된 대각선이 N 개의 고유 한 요소 집합의 각 요소를 정확히 한 번 포함하도록하는 NxN 그리드) 만 생성해야한다는 개념입니다. 알파벳. 만약 우리가 그러한 대각선 라틴 광장 (DLS)을 만들 수 있다면, 적절한 요소 교환과 뒤집기와 함께 DLS를 사용하여 ODLS를 만들 수 있습니다. 정당화:
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.
두 번째 단순화는 하나의 요소 (각 행, 열, 래핑 된 대각선이 해당 요소를 정확히 한 번 포함하는 NxN 그리드)의 적절한 구성 (SC)을 발견하면 요소를 교체하여 DLS를 구성 할 수 있다는 개념입니다. 및 SC를 이동시키는 단계. 정당화:
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.
마지막 단순화는 다음과 같습니다-N = 2 또는 N = 3을 제외한 소수 N의 모든 DLS를 구성 할 수 있으며, N을 적절한 DLS를 구성 할 수있는 두 개의 숫자로 분해 할 수 있으면 해당 N의 DLS는 건설된다. 나는 그 대화가 또한 가지고 있다고 추측한다. (즉, 우리는 2 또는 3으로 나눌 수없는 N에 대한 DLS 만 구성 할 수 있습니다)
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)