Xây dựng một quảng trường Greco-Latin trực giao


11

Hãy xem xét một lưới gồm các yếu tố Nx Nduy nhất. Mỗi phần tử có một chữ cái (từ A đến Nchữ cái, bao gồm) và một số (từ 1 đến N, bao gồm). Do đó, mỗi cặp số / chữ cái nằm trong lưới chính xác một lần.

Công việc của bạn là sắp xếp một lưới sao cho:

Mỗi hàng, cột và đường chéo (bao gồm cả gói) chứa mỗi chữ cái và số chính xác một lần.

Bằng cách gói, tôi có nghĩa là

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

là một đường chéo, cùng với tất cả các đường chéo tương tự đánh vào các cạnh.

Một 5x5lưới ví dụ là:

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

Nhiệm vụ của bạn là viết một chương trình chấp nhận một số Nvà in lưới Nx Nnhư mô tả ở trên. Chương trình của bạn nên làm việc cho bất kỳ 0 < N <= 26. Nếu một lưới cụ thể là không thể, thì bạn nên in Impossible.

Mã hóa câu trả lời cho bất kỳ Nlà không được phép. Một chương trình được mã hóa cứng nếu nó tính toán lưới theo cách khác (theo đánh giá của tôi) cho bất kỳ N > 26(hoặc nếu nó không tính toán). (Điều này có nghĩa là để ngăn chặn sự tính toán trước, bao gồm các lưới không hợp lệ được tính toán trước hoặc bù đắp cho các lưới đã cho).

Đây là một vấn đề mã nhanh nhất và điểm của bạn là tổng số lần thực hiện để chạy chương trình của bạn trên tất cả các khả năng có thể Ntrên máy tính của tôi. Trong câu trả lời của bạn, vui lòng để chương trình của bạn chạy trên tất cả N(vì vậy tôi chỉ phải tính thời gian một lần). Nếu không có chương trình nào có thể tính toán nó trong vòng dưới 60 giây, thì người chiến thắng là câu trả lời có thể tính toán lưới lớn nhất Ntrong 60 giây. Nếu nhiều chương trình có cùng mức tối đa N, thì tiebreaker là giải pháp nhanh nhất.

(Tôi có một máy Windows 8 hoạt động mạnh mẽ và mọi trình biên dịch hoặc thông dịch viên cần phải có sẵn miễn phí cho nó).


Thực tế là máy của bạn là Windows chứ không phải Linux có thể gây khó chịu cho một số công nghệ.
orlp

+1 cho câu hỏi, nhưng khi phân tích ví dụ của bạn dường như cho ra một thuật toán khá nhanh, tôi tự hỏi liệu bạn có thực sự có thể đo được tốc độ không. Chúng ta có thể viết một hàm trả về một chuỗi không? Bởi vì tôi tin rằng thời gian các lệnh gọi API thực hiện in ấn thực tế sẽ dài hơn thời gian tính toán.
Cấp sông St

@steveverrill có, với mục đích thời gian, trả về một chuỗi là chấp nhận được.
Nathan Merrill

Mục đích của chữ và số. Có phải mỗi số chỉ xuất hiện bên cạnh mỗi chữ cái một lần, hoặc 1 có thể luôn xuất hiện bên cạnh A, 2 bên cạnh B, ...?
Jakube

@Jakube có. Mỗi phần tử phải là duy nhất, nghĩa là mỗi cặp số / chữ cái trong lưới phải là duy nhất.
Nathan Merrill

Câu trả lời:


5

Con trăn 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")

Làm thế nào nó hoạt động?

Việc triển khai ngây thơ sẽ là xem xét tất cả các cách sắp xếp chữ cái và số trong lưới NxN và tìm kiếm một hình vuông cũng là một hình vuông Latin trực giao (ODLS) (và do đó, đối với một số người sẽ phải trải qua tất cả cấu hình và trả lại không thể). Một thuật toán như vậy sẽ không phù hợp với thách thức này do độ phức tạp thời gian vô lý. Vì vậy, có ba đơn giản hóa và biện minh chính (bằng chứng một phần và hiểu biết về lý do tại sao nó hoạt động) đối với các cấu trúc ODLS được sử dụng trong triển khai của tôi:

Đầu tiên là khái niệm rằng chúng ta chỉ cần tạo một Quảng trường Latinh chéo hợp lệ (Lưới NxN sao cho mỗi hàng, cột, đường chéo được chứa mỗi phần tử của một tập hợp N phần tử riêng biệt chính xác một lần) của N chữ cái đầu tiên của bảng chữ cái. Nếu chúng ta có thể xây dựng một Quảng trường Latin chéo (DLS) như vậy thì ODLS có thể được xây dựng bằng cách sử dụng DLS với sự trao đổi các yếu tố và lật phù hợp. Biện minh

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.

Đơn giản hóa thứ hai là khái niệm rằng nếu chúng ta tìm thấy một cấu hình phù hợp (SC) của một phần tử (Lưới NxN sao cho mỗi hàng, cột, đường chéo có chứa phần tử đó chính xác một lần), thì có thể xây dựng DLS bằng cách thay thế phần tử và thay đổi SC. Biện minh

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 giản hóa cuối cùng như sau - tất cả DLS của số nguyên tố N, ngoại trừ N = 2 hoặc N = 3, có thể được xây dựng và nếu N có thể được chia thành hai số có thể xây dựng DLS thích hợp, thì DLS của N có thể được xây dựng được xây dựng. Tôi phỏng đoán rằng converse cũng giữ. (Nói cách khác, chúng ta chỉ có thể xây dựng một DLS cho N không chia hết cho 2 hoặc 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 

nhập mã vào đây

Một bức tranh về ý nghĩa của tôi với DLS nhỏ hơn - lớn hơn

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.