Sản xuất quảng trường ma thuật của Dürer


14

Các thách thức

Xuất ra một mảng hoặc chuỗi đại diện cho quảng trường ma thuật nổi tiếng của Dürer :

nhập mô tả hình ảnh ở đây

đó là,

16  3  2 13
 5 10 11  8
 9  6  7 12
 4 15 14  1

Một số thuộc tính của hình vuông này, có lẽ có thể được khai thác, là:

  • Nó chứa mỗi số nguyên từ 1đến 16đúng một lần
  • Tổng của mỗi cột hoặc hàng, cũng như tổng của mỗi trong hai đường chéo, là như nhau. Đây là thuộc tính xác định của một hình vuông ma thuật . Tổng là hằng số ma thuật của hình vuông.
  • Ngoài ra, đối với hình vuông đặc biệt này, tổng của bốn góc phần tư cũng bằng hằng số ma thuật, cũng như tổng của bốn hình vuông trung tâm và tổng của bốn hình vuông góc.

Quy tắc

Bultin tạo ra các ô vuông ma thuật không được phép (chẳng hạn như của Matlab magichoặc Mathicala MagicSquare). Bất kỳ nội dung khác có thể được sử dụng.

Mã có thể là một chương trình hoặc một chức năng.

Không có đầu vào.

Các số phải ở cơ sở 10. Định dạng đầu ra linh hoạt như bình thường. Một số khả năng là:

  • Mảng lồng nhau (đầu ra hàm hoặc biểu diễn chuỗi của nó, có hoặc không có dấu phân cách, bất kỳ loại dấu ngoặc khớp nào):

    [[16, 3, 2, 13], [5, 10, 11, 8], [9, 6, 7, 12], [4, 15, 14, 1]]
    
  • Một mảng 2D:

    {16, 3, 2, 13; 5, 10, 11, 8; 9, 6, 7, 12; 4, 15, 14, 1}
    
  • Một mảng gồm bốn chuỗi, hoặc một chuỗi bao gồm bốn dòng. Các số có thể được căn phải

    16  3  2 13
     5 10 11  8
     9  6  7 12
     4 15 14  1
    

    hoặc căn trái

    16 3  2  13
    5  10 11  8
    9  6  7  12
    4  15 14  1
    
  • Một chuỗi có hai dấu phân cách khác nhau cho hàng và cột, chẳng hạn như

    16,3,2,13|5,10,11,8|9,6,7,12|4,15,14,1
    

Các định dạng đầu ra nên phân biệt rõ ràng các hàng và cột. Ví dụ, không được phép xuất ra một mảng phẳng hoặc một chuỗi có tất cả các số được phân tách bằng dấu cách.

Mã golf. Chiến thắng ngắn nhất.



4
Điều thú vị là, các số 5, 8, 9 và 12 nằm ở vị trí (1 chỉ mục) của chúng, 6, 7, 10 và 11 đã được phản ánh theo chiều dọc, 2, 3, 14 và 15 đã được phản ánh theo chiều ngang và 1, 4, 13 và 16 đã được quay 180 °. Tôi nghi ngờ rằng sẽ giúp bất cứ ai mặc dù.
Neil

2
Quan sát có thể hữu ích: nếu bạn giảm 1 từ mỗi số, bạn có thể tạo hình vuông bằng cách bắt đầu với mảng [15], sau đó liên tục nối nó với mặt sau của nó với mỗi mục XOR lần lượt là 13, 3, 8 và 15.
Sản xuất ETH

6
Điều này có vẻ khá khó để nén trong các ngôn ngữ không chơi gôn. tôi nghĩ rằng một hình vuông ma thuật lớn hơn sẽ làm tốt hơn.
xnor

1
Tôi khá chắc chắn mỗi vòng quay hoặc hình phản chiếu của hình vuông sẽ có cùng thuộc tính.
Dennis

Câu trả lời:


7

Thạch , 15 byte

“¡6ṡƘ[²Ḳi<’ḃ⁴s4

Dùng thử trực tuyến!

Khá nhàm chán, xin lỗi:

Chuẩn bị: Lấy hình vuông, đọc nó theo hàng, được chuyển đổi từ cơ sở phỏng đoán 16, chuyển đổi nó thành cơ sở 250, tra cứu các chỉ mục trang mã cho các "chữ số" ( ¡6ṡƘ[²Ḳi<) đó.

Jelly sau đó đọc các chỉ mục để tạo ra một số cơ sở 250, chuyển đổi thành cơ sở phỏng đoán 16 ( ḃ⁴) và chia thành các khối có kích thước 4 ( s4).


Nếu chúng ta được phép đưa ra một hướng khác, việc lộn ngược có thể xảy ra trong 14 :

“#⁷ƙ¤ṆWȷỤ’ḃ⁴s4

Kiểm tra


Về lý thuyết, việc cung cấp đủ bộ nhớ cho 16!các số nguyên sau đây sẽ cho chúng ta định hướng chính xác trong 14 :

⁴Œ!“ŒCġŀḌ;’ịs4

Điều này sẽ tạo ra tất cả các hoán vị của [1,16] với ⁴Œ!và chọn giá trị ở chỉ số 1980059 3106060 (dựa trên 1) bằng cách sử dụng biểu diễn 250 cơ sở ŒCġŀḌ;và chia nó thành các đoạn có độ dài 4 với s4.


Kể từ đó tôi đã thêm bốn nguyên tử mới ( Œ?, Œ¿, œ?, và œ¿) để Jelly đến địa chỉ tình huống như vậy.
Đơn vị Œ?lấy một số nguyên (hoặc có thể lặp lại các số nguyên) và trả về phép hoán vị ngắn nhất có thể có của các số tự nhiên có chỉ số (hoặc chỉ mục) đã cho trong danh sách liệt kê tất cả các hoán vị của các số đó.
... Và nó làm như vậy mà không tạo ra bất kỳ danh sách hoán vị.
Vì vậy, sau đây sẽ hoạt động cho 12 (rõ ràng là không cạnh tranh):

“ŒCġŀḌ;’Œ?s4

Thôi buông đi!


Điều này nên ngắn hơn trong ngã ba Jelly của bạn (điều mà tôi đã quên cho đến tận bây giờ, xin lỗi).
Dennis

Oh? Bạn nghĩ như thế nào?
Jonathan Allan

8

Bình thường, 18 byte

c4.PC"H#ût"_S16

Chạy mã.

c4.PC"H#ût"_S16

    C"H#ût"       Convert the packed string to the number 1122196781940
  .P       _S16   Take that-numbered permutation of the reversed range [16,15,...,1]
c4                Chop into piece of length 4

Đảo ngược phạm vi có nghĩa là để giảm chỉ số hoán vị, vì đầu ra bắt đầu bằng 16, nhưng tôi nghĩ nó chỉ hòa vốn.

Điều này đánh bại một chiến lược nhàm chán hơn là chuyển đổi bảng trực tiếp thành cơ sở 17 và sau đó là một chuỗi ( liên kết ) cho 20 byte:

c4jC"úz(ás¸H"17 

7

Thạch , 16 15 byte

4Œ!.ịm0µZḂÞ’×4+

Hãy thử trực tuyến!

Lý lịch

Nếu chúng ta trừ 1 từ các số trong hình vuông và chia chúng cho 4 (tính thương số và phần còn lại), một mô hình sẽ trở nên rõ ràng.

quotients and remainders    quotients    remainders

   3 3  0 2  0 1  3 0        3 0 0 3      3 2 1 0
   1 0  2 1  2 2  1 3        1 2 2 1      0 1 2 3
   2 0  1 1  1 2  2 3        2 1 1 2      0 1 2 3
   0 3  3 2  3 1  0 0        0 3 3 0      3 2 1 0

Ma trận còn lại theo một mô hình rõ ràng và dễ dàng tạo ra. Ma trận thương có thể thu được bằng cách hoán vị ma trận còn lại và hoán đổi các hàng giữa.

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

4Œ!.ịm0µZḂÞ’×4+  Main link. No arguments.

4Œ!              Compute the array of all permutations of [1, 2, 3, 4], in
                 lexicographical order.
   .ị            Take the permutations at the indices adjacent to 0.5, i.e., the
                 ones at indices 0 ([4, 3, 2, 1]) and 1 ([1, 2, 3, 4]).
     m0          Concatenate the resulting [[4, 3, 2, 1], [1, 2, 3, 4]] with a
                 reversed copy, yielding the matrix
                 M := [[4, 3, 2, 1], [1, 2, 3, 4], [1, 2, 3, 4], [4, 3, 2, 1]].
       µ         Begin a new, monadic chain. Argument: M
        Z        Zip/transpose M, yielding the matrix
                 [[4, 1, 1, 4], [3, 2, 2, 3], [2, 3, 3, 2], [1, 4, 4, 1]].
         ḂÞ      Sort the rows by the lexicographical order of their parities,
                 yielding [[4, 1, 1, 4], [2, 3, 3, 2], [3, 2, 2, 3], [1, 4, 4, 1]].
           ’     Subtract 1 to yield the matrix of quotients, i.e.,
                 [[3, 0, 0, 3], [1, 2, 2, 1], [2, 1, 1, 2], [0, 3, 3, 0]].
            ×4+  Multiply the quotient by 4 and add the result to M (remainders).

5

J, 37 27 byte

Saved 10 byte nhờ dặm!

4 4$1+19800593106059 A.i.16

Bây giờ với ít nhàm chán! Điều này có 19800593106059hoán vị của danh sách i.16, đó là 15 2 1 12 4 9 10 7 8 5 6 11 3 14 13 0. Sau đó, có nghĩa là tăng lên, sau đó là hình thành một 4bằng 4danh sách.

Phiên bản thay thế, không có khoảng trắng:

_4]\1+19800593106059&A.i.16

Đầu ra, cho hậu thế:

   _4]\1+19800593106059&A.i.16
16  3  2 13
 5 10 11  8
 9  6  7 12
 4 15 14  1
   4 4$1+19800593106059 A.i.16
16  3  2 13
 5 10 11  8
 9  6  7 12
 4 15 14  1

Tôi nghĩ rằng _4]\1+19800593106059&A.i.16công trình nhưng nó có thể được thực hiện ngắn hơn có thể
dặm

@miles oo, sử dụng tốt đẹp A.. Làm thế nào bạn vây số đó?
Conor O'Brien

Monadic A.thấy chỉ số hoán vị của một hoán vị zero-lập chỉ mục
dặm

@miles hả. Tôi đoán tôi nên tìm hiểu thêm một chút về các chức năng đó.
Conor O'Brien


4

Ruby, 49 byte (ngắn hơn giải pháp ngây thơ!)

Phải mất khá nhiều nỗ lực để viết một đoạn trích cho thử thách này bằng ngôn ngữ chính ngắn hơn so với những gì nó đánh giá! Theo quy tắc thông thường, tôi đã tạo một chương trình từ nó bằng cách thêm một pđể xuất nó.

p [15,4,8,3].map{|i|[1+i,1+i^=13,1+i^=3,1+i^=13]}

Nó xuất ra (biểu diễn chuỗi của) một mảng các mảng. Nó dài hơn giải pháp Ruby của wat tạo ra một chuỗi có định dạng khác nhau, nhưng ngắn hơn một byte so với chương trình ngây thơ dưới đây chỉ đơn giản trả về mảng bằng chữ.

p [[16,3,2,13],[5,10,11,8],[9,6,7,12],[4,15,14,1]] #naive solution, 50 bytes
p [15,4,8,3].map{|i|[1+i,1+i^=13,1+i^=3,1+i^=13]}  #submission, 49 bytes

Giải thích: bắt đầu bằng số 0..15 (38 byte!)

Đây là nơi tôi đã bắt đầu và nó dễ dàng hơn nhiều. Nếu chúng ta chuyển đổi ô vuông 0,15 thành nhị phân, chúng tôi lưu ý rằng mỗi ô chứa giá trị ở dưới cùng của cột XORed với giá trị ở phía bên phải của hàng:

15 2  1  12            1111 0010 0001 1100
4  9  10 7             0100 1001 1010 0111
8  5  6  11            1000 0101 0110 1011
3  14 13 0             0011 1110 1101 0000

Từ đó, chúng tôi rút ra mã dưới đây. Nhưng bằng cách sử dụng cột đầu tiên thay vì cột cuối cùng, chúng tôi lưu một byte, như được hiển thị.

p [12,7,11,0].map{|i|[i^3,i^14,i^13,i]}            #0..15 square, 39 bytes         
p [15,4,8,3].map{|i|[i,i^13,i^14,i^3]}             #0..15 square, 38 bytes

Phiên bản 1..16 cần thiết là khó khăn hơn. Cuối cùng, tôi nhận ra cách để làm điều đó là thêm 1 vào mỗi ô của ô vuông 0,15. Nhưng như ^có mức độ ưu tiên thấp hơn +tôi cần rất nhiều dấu ngoặc đơn, đã ăn byte. Cuối cùng tôi đánh vào ý tưởng sử dụng ^=. Giá trị mới của iđược tính bằng phép gán tăng ^=trước khi thêm 1 vào nó, vì vậy phép tính được thực hiện theo đúng thứ tự.


Đặc tính tốt đẹp! Một nhận thức đơn giản trong Python là 6 ký tự trên mã cứng : for a in 12,7,11,0:print[(a^b)+1for b in 3,14,13,0]. Nó sẽ thắng nếu chúng ta có thể làm 0 đến 15 với for a in 12,7,11,0:print[a^3,a^14,a^13,a].
xnor

3

JavaScript (ES6), 43 byte

_=>`16,3,2,13
5,10,11,8
9,6,7,12
4,15,14,1`

Phân tách bằng dòng mới, sau đó dấu phẩy. Tôi nghi ngờ có cách nào ngắn hơn ...


Vâng, đây có lẽ là ngắn nhất có thể.
Conor O'Brien

2

sed 39 byte

c16,3,2,13|5,10,11,8|9,6,7,12|4,15,14,1

Hãy thử trực tuyến!

Nó không thể đơn giản hơn thế này nhiều. Và thật không may, tôi cũng không nghĩ nó có thể ngắn hơn nữa.



2

DASH , 24 byte

<|>4tc"................"

Thay thế các dấu chấm bằng các ký tự của mã số 16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14 và 1 tương ứng.

Giải trình

Đơn giản chỉ cần chuyển đổi các ký tự thành một mảng các mã và khối bằng 4.


2

Trên thực tế , 22 byte

4"►♥☻♪♣◙♂◘○♠•♀♦☼♫☺"♂┘╪

Hãy thử trực tuyến!

Giải trình:

4"►♥☻♪♣◙♂◘○♠•♀♦☼♫☺"♂┘╪
 "►♥☻♪♣◙♂◘○♠•♀♦☼♫☺"     push a string containing the numbers in the magic square, encoded as CP437 characters
                   ♂┘   convert to ordinals
4                    ╪  chunk into length-4 slices

2

Groovy, 57 byte / 46 byte

"F21C49A7856B3ED0".collect{Eval.me("0x$it")+1}​.collate(4)​

Phân tích từng cái dưới dạng chữ số thập lục phân và thêm 1, đối chiếu 4 thành một mảng 2D.

[[16, 3, 2, 13], [5, 10, 11, 8], [9, 6, 7, 12], [4, 15, 14, 1]]

Ngắn hơn, nhưng cũng than thở:

print '16,3,2,13|5,10,11,8|9,6,7,12|4,15,14,1'

2

Javascript ES6, 66 65 55 byte

Vâng, nó không phải là ngắn nhất. Và vâng, nó có thể được giảm.

_=>`f21c
49a7
856b
3ed0`.replace(/./g,_=>'0x'+_-~0+' ')

Hiện tại, nó không hoàn hảo. Nhưng là một cái gì đó!


Nhờ đề xuất của @Neil có thể tiết kiệm 5-8 byte và đề xuất @ETHproductions lấy cảm hứng đó tiết kiệm 10 byte!

Điều này làm cho câu trả lời chỉ dài hơn 12 byte so với giải pháp 43 byte của anh ta .


1
Bạn có thể sử dụng gthay vì 0parseInt(c,17)thay vào đó, điều mà tôi nghĩ giúp bạn tiết kiệm 4 byte hoặc bạn có thể sử dụng + 0x${c}|| 16, tôi nghĩ bạn tiết kiệm được 5 byte và sau đó bạn có thể trừ 1 từ tất cả các chữ số và thêm lại sau đó, mà tôi nghĩ giúp bạn tiết kiệm một byte khác.
Neil

1
Dựa trên đề xuất của @ Neil, bạn có thể tiết kiệm tổng cộng ít nhất 10 byte .
Sản xuất ETH

@Neil Cảm ơn bạn rất nhiều vì ý tưởng. Sử dụng base17 thực sự tiết kiệm một vài byte. Nó thực sự là một cái gì đó tôi đã không nghĩ về.
Ismael Miguel

@ETHproductions Cảm ơn bạn rất nhiều vì gợi ý! Tôi vẫn đang cố gắng để hiểu làm thế nào nó hoạt động. Nhưng tôi nghĩ tôi sẽ đến đó. Bây giờ, chỉ cần rút ngắn 13 byte để đánh bại bạn. Nhưng có vẻ như câu trả lời của bạn là ngắn nhất có thể trong Javascript
Ismael Miguel

1

PowerShell v2 +, 40 byte

'16,3,2,13
5,10,11,8
9,6,7,12
4,15,14,1'

Một chuỗi multiline theo nghĩa đen, còn lại trên đường ống. Đầu ra thông qua ngầm Write-Outputxảy ra khi hoàn thành chương trình. Đẹp và nhàm chán.


Phiên bản xây dựng, 77 byte

'f21c59a7856b3dc0'-split'(....)'-ne''|%{([char[]]$_|%{"0x$_+1"|iex})-join','}

Lấy chuỗi, -splitcứ bốn phần tử, lặp lại chúng, thay đổi từng chuỗi thành một hình lục giác 0x$_và thêm 1, các ống dẫn iex(viết tắt Invoke-Expressionvà tương tự eval), sau đó -joinkết quả thành một chuỗi với ,dấu phân cách. Xuất ra bốn chuỗi trên đường ống, với in ấn ngầm.


1

Ruby, 60 byte - lần thử đầu tiên

%w(f21c 49a7 856b 3ed0).map{|i|i.chars.map{|i|i.to_i(16)+1}}

Ruby, 45 byte - giá rẻ

puts '16,3,2,13|5,10,11,8|9,6,7,12|4,15,14,1'


1

05AB1E , 15 byte

16Lœ•iPNÍš¯•è4ä

Giải trình

16L              # range [1 ... 16]
   œ             # compute all permutations of the range
    •iPNÍš¯•è    # take the permutation at index 19800593106059
             4ä  # split the permutation into 4 parts

Chỉ số của hoán vị được tìm thấy bằng cách sử dụng công thức:

a*15! + b*14! + c*13!+ ... + o*1! + p*0!

Trong đó các biến được thay thế bằng số phần tử thành công nhỏ hơn số tại chỉ mục hiện tại cho mỗi số trong danh sách mục tiêu
[16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14, 1]

mà cho hoán vị tìm kiếm của chúng tôi là
a=15, b=2, c=1, d=10, e=2, f=6, g=6, h=4, i=4, j=2, k=2, l=2, m=1, n=2 o=1, p=0

Điều này cho chúng ta công thức: 15*15!+2*14!+1*13!+10*12!+2*11!+6*10!+6*9!+4*8!+4*7!+2*6!+2*5!+2*4!+1*3!+2*2!+1*1!+0*0!

bằng với 19800593106059.


1

Matlab, 38 35 byte

Hàm ẩn danh:

@()['pcbm';'ejkh';'ifgl';'dnoa']-96

In trực tiếp (38 byte):

disp(['pcbm';'ejkh';'ifgl';'dnoa']-96)

Trong Matlab cách tốt nhất để tạo ra một mảng các số nguyên là một chuỗi.


Sử dụng một hàm ẩn danh sẽ tiết kiệm được một vài byte:@()['pcbm';'ejkh';'ifgl';'dnoa']-96
Luis Mendo

@LuisMendo Tôi không nhận thấy rằng giá trị trả về cũng được chấp nhận, cảm ơn!
pyjama

1

Scala, 52 byte

()=>Seq(15,4,8,3)map(x=>Seq(x,x^13,x^14,x^3)map(1+))

Ung dung:

()=>
  Seq(15, 4, 8, 3)
  .map(x=>
    Seq(x, x^13, x^14, x^3)
    .map(1+)
  )

Lấy cảm hứng từ Cấp sông St của câu trả lời ruby .

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.