뒤러의 마법 광장 제작


14

도전

Dürer의 유명한 매직 스퀘어 의 배열 또는 문자열 표현을 출력하십시오 .

여기에 이미지 설명을 입력하십시오

그건,

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

이 사각형의 일부 속성 은 다음과 같이 활용 될 수 있습니다.

  • 각 정수 116정확히 한 번에 포함합니다.
  • 각 열 또는 행의 합과 두 대각선의 합은 동일합니다. 이것은 매직 스퀘어 의 정의 속성입니다 . 합계는 제곱 의 마법 상수 입니다.
  • 또한,이 특정 제곱에 대해, 4 개의 사분면 각각의 합은 중심 4 제곱의 합과 코너 4 제곱의 합과 마찬가지로 마법 상수와 같습니다.

규칙

매직 스퀘어를 생성하는 Bultin은 허용되지 않습니다 (예 : Matlab magic또는 Mathematica MagicSquare). 다른 내장 기능을 사용할 수 있습니다.

코드는 프로그램 또는 함수일 수 있습니다.

입력이 없습니다.

숫자는 10 진수 여야합니다. 출력 형식은 평소처럼 유연합니다. 몇 가지 가능성은 다음과 같습니다.

  • 중첩 배열 (함수 출력 또는 문자열 구분 기호 (구분 기호 포함 또는 제외), 모든 유형의 일치하는 괄호) :

    [[16, 3, 2, 13], [5, 10, 11, 8], [9, 6, 7, 12], [4, 15, 14, 1]]
    
  • 2D 배열 :

    {16, 3, 2, 13; 5, 10, 11, 8; 9, 6, 7, 12; 4, 15, 14, 1}
    
  • 네 개의 문자열로 구성된 배열 또는 네 개의 줄로 구성된 문자열 숫자는 오른쪽 정렬 일 수 있습니다

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

    또는 왼쪽 정렬

    16 3  2  13
    5  10 11  8
    9  6  7  12
    4  15 14  1
    
  • 행과 열에 대해 두 개의 다른 구분 기호가있는 문자열

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

출력 형식은 행과 열을 명확하게 구분해야합니다. 예를 들어, 플랫 배열 또는 모든 숫자가 공백으로 구분 된 문자열을 출력 할 수 없습니다.

코드 골프. 최단 승리.



4
흥미롭게도 숫자 5, 8, 9 및 12는 (1- 인덱스) 위치에 있으며, 6, 7, 10 및 11은 수직으로 반영되었고, 2, 3, 14 및 15는 수평으로 반영되었으며 1, 4, 13은 16은 180도 회전했습니다. 나는 그것이 누군가를 도울 것이라고 의심합니다.
Neil

2
아마도 유용한 관찰 : 각 숫자에서 1을 줄이면 array로 시작하여 제곱을 생성 [15]한 다음 각각 13, 3, 8 및 15로 XOR 된 각 항목과 그 반대로 반복하여 연결할 수 있습니다.
ETHproductions

6
비 골프 언어에서는 압축하기가 다소 어려워 보입니다. 나는 더 큰 마술 광장이 더 잘했을 것이라고 생각합니다.
xnor

1
사각형의 각 회전 또는 반사가 동일한 속성을 가질 것이라고 확신합니다.
Dennis

답변:


7

젤리 , 15 바이트

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

TryItOnline!

꽤 지루합니다. 죄송합니다.

준비 : 정사각형을 가져 와서 행으로 읽은 다음 bijective base 16에서 변환하여 base 250으로 변환하고 해당 "숫자"( ¡6ṡƘ[²Ḳi<)에 대한 코드 페이지 색인을 찾습니다 .

그런 다음 Jelly는 색인을 읽고 밑이 250 인 숫자를 만들고, bijective 밑을 16 ( ḃ⁴)으로 변환하고 크기가 4 ( s4) 인 청크로 분할 합니다.


다른 방향으로 출력 할 수 있다면 14 에서 거꾸로 가능합니다 .

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

테스트


이론적으로 16!정수에 충분한 메모리 가 제공되면 다음은 14 의 올바른 방향을 제공합니다 .

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

이렇게하면 [1,16]의 모든 순열이 생성 되고 밑이 250 인 표현 ⁴Œ!사용하여 인덱스 19800593106060 (1 기반)의 값을 선택하고을 사용하여 ŒCġŀḌ;길이가 4 인 청크로 분할합니다 s4.


그 이후로 나는 네 개의 새로운 원자를 (추가 한 Œ?, Œ¿, œ?, 및 œ¿주소 등의 상황에 젤리로).
모나드 Œ?는 정수 (또는 정수의 반복 가능)를 취하고 해당 숫자의 모든 순열의 사전 순으로 정렬 된 목록의 목록에서 주어진 색인 (또는 색인)을 갖는 연속 자연수의 가능한 가장 짧은 순열을 리턴합니다.
... 순열 목록을 만들지 않고 그렇게합니다.
따라서 다음은 12에서 작동합니다 (분명히 경쟁하지 않음).

“ŒCġŀḌ;’Œ?s4

줘!


이것은 젤리 포크에서 짧아야합니다 (지금까지 잊어 버린 죄송합니다).
Dennis

오? 당신은 어떻게 생각하십니까?
Jonathan Allan

8

Pyth, 18 바이트

c4.PC"H#ût"_S16

코드를 실행하십시오.

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

출력을 16으로 시작하기 때문에 범위를 바꾸면 순열 지수를 낮추는 것이었지만, 나는 심지어 짝수라고 생각합니다.

이것은 테이블을 기본 17로 직접 변환 한 다음 20 바이트 동안 문자열 ( link )을 변환하는보다 지루한 전략을 능가했습니다 .

c4jC"úz(ás¸H"17 

7

젤리 , 16 15 바이트

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

온라인으로 사용해보십시오!

배경

우리 가 정사각형의 숫자에서 1 을 빼고 4로 나누면 (몫과 나머지를 계산) 패턴이 분명해집니다.

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

나머지 행렬은 명백한 패턴을 따르며 생성하기 쉽습니다. 몫 행렬은 나머지 행렬을 바꾸고 가운데 행을 교환하여 얻을 수 있습니다.

작동 원리

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 바이트

마일 덕분에 10 바이트를 절약했습니다!

4 4$1+19800593106059 A.i.16

이제 덜 지루한! 이것은 소요 19800593106059목록의 순열 i.16이다 15 2 1 12 4 9 10 7 8 5 6 11 3 14 13 0. 그런 다음 증분 된 다음 목록 4별로 모양이 지정됩니다 4.

공백이없는 대체 버전 :

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

후손을위한 출력 :

   _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

내가 생각하는 _4]\1+19800593106059&A.i.16일을하지만 가능성이 짧아을 만들 수있는
마일

@ 마일 OO, 잘 사용 A.합니다. 그 번호를 어떻게 지웠습니까?
코너 오브라이언

모나드는 A.순열 제로 인덱스 순열의 인덱스 발견
마일

@ 마일리지. 그 기능에 대해 조금 더 배워야 할 것 같습니다.
Conor O'Brien


4

루비, 49 바이트 (순진한 솔루션보다 짧음)

이 도전 과제에 대한 스 니펫을 주류 언어로 작성하는 데는 몇 번의 시도가 필요했습니다. 일반적인 규칙에 따라 p출력 을 추가하여 프로그램을 만들었 습니다.

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

배열 배열을 출력합니다 (문자열 표현). 형식이 다른 문자열을 출력하는 것은 와트의 루비 솔루션보다 길지만 아래의 순진 프로그램보다 1 바이트 짧아 리터럴 배열을 반환합니다.

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

설명 : 숫자 0..15 (38 바이트)로 시작하십시오.

이것은 내가 시작한 곳이며 훨씬 쉽습니다. 0..15 제곱을 이진수로 변환하면 각 셀의 열 맨 아래에 값이 있고 행의 오른쪽에 값이 있습니다.

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

이것으로부터 우리는 아래 코드를 도출합니다. 그러나 마지막 열 대신 첫 번째 열을 사용하면 그림과 같이 1 바이트를 절약 할 수 있습니다.

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

필요한 1..16 버전이 더 어려웠습니다. 결국 나는 그것이 0..15 사각형의 각 셀에 1을 추가하는 방법을 깨달았습니다. 그러나 ^우선 순위가 낮을수록 +바이트를 먹는 많은 괄호가 필요했습니다. 마지막으로를 사용하는 아이디어에 부딪쳤다 ^=. 새로운 값은 1이 추가되기 전에 i증강 된 할당으로 ^=계산되므로 정확한 순서로 계산됩니다.


좋은 특성화! 파이썬에서 간단한 구현은 하드 코드 위의 6 자입니다 : for a in 12,7,11,0:print[(a^b)+1for b in 3,14,13,0]. 로 0에서 15까지 할 수 있다면 이길 것입니다 for a in 12,7,11,0:print[a^3,a^14,a^13,a].
xnor

3

자바 스크립트 (ES6), 43 바이트

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

줄 바꿈으로 구분 한 다음 쉼표로 구분하십시오. 더 짧은 방법이 있는지 의심합니다 ...


네, 아마도 가장 짧은 것입니다.
Conor O'Brien



2

DASH , 24 바이트

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

마침표를 각각 16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14 및 1의 문자로 바꿉니다.

설명

단순히 문자를 4의 문자 코드 및 청크 배열로 변환합니다.


2

실제로 , 22 바이트

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

온라인으로 사용해보십시오!

설명:

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

그루비, 57 바이트 / 46 바이트

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

각각 16 진 숫자로 구문 분석하고 1을 추가하고 2를 기준으로 4 씩 정렬합니다.

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

짧지 만 라머 :

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

2

자바 스크립트 ES6, 66 65 55 바이트

예, 가장 짧은 것은 아닙니다. 그렇습니다, 그것은 감소 될 수 있습니다.

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

지금은 완벽하지 않습니다. 그러나 뭔가입니다!


덕분에 @Neil 5-8 바이트를 절약 할 수의 제안, 그리고 영감 @ETHproductions 10 바이트를 저장 제안!

이것은 그의 43 바이트 솔루션 보다 12 바이트 만 답을 만든다 .


1
당신이 사용할 수있는 g대신 0parseInt(c,17)내가 너희 4 바이트 저장 생각하는 대신하거나 + 사용할 수 있습니다 0x${c}, 당신 5 바이트 저장 생각 || (16)을, 그리고 당신은 그 모든 숫자 1을 뺄 수 있고 나중에 다시 추가 나는 당신에게 또 다른 바이트를 절약한다고 생각합니다.
Neil

1
@Neil의 제안을 바탕으로 총 10 바이트 이상을 절약 할 수 있습니다 .
ETHproductions

@Neil 아이디어를 주셔서 감사합니다. base17을 사용하면 실제로 몇 바이트가 절약됩니다. 정말 내가 생각하지 않은 것입니다.
이스마엘 미겔

@ETHproductions 제안 해 주셔서 감사합니다! 나는 아직도 그것이 어떻게 작동하는지 이해하려고 노력하고 있습니다. 그러나 나는 거기에 갈 것이라고 생각한다. 이제, 당신을 이길 13 바이트를 단축해야합니다. 그러나 당신의 대답은 자바 스크립트에서 가장 짧은 것 같습니다
Ismael Miguel

1

PowerShell v2 +, 40 바이트

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

파이프 라인에 남겨진 리터럴 멀티 라인 문자열. 암시 적 출력 Write-Output은 프로그램 완료시 발생합니다. 좋고 지루합니다.


생성 된 버전, 77 바이트

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

문자열을 가져 -split와서 4 개의 요소마다 반복하고, 각각의 요소를 16 진으로 변경하고을 0x$_추가 1하고 iex(단축 Invoke-Expression및 유사 eval) 파이프를 분리 한 다음 -join결과를 ,구분자 로 사용하여 문자열에 결과를 저장합니다 . 암시 적 인쇄로 파이프 라인에 4 개의 문자열을 출력합니다.


1

루비, 60 바이트-첫 시도

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

루비, 45 바이트-저렴한

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


1

05AB1E , 15 바이트

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

설명

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

순열의 인덱스는 다음 공식을 사용하여 발견되었습니다.

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

변수가 대상 목록의 각 숫자에 대한 현재 색인의 숫자보다 작은 후속 요소의 수로 대체되는 경우
[16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14, 1]

순열 후 우리가 추구하는 것은
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

이것은 우리에게 공식을 제공합니다 : 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!

어느 것과 같습니다 19800593106059.


1

MATLAB, 38 35 바이트

익명의 기능 :

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

직접 인쇄 (38 바이트) :

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

Matlab에서 정수 배열을 생성하는 가장 좋은 방법은 문자열입니다.


익명 함수를 사용하면 몇 바이트를 절약 할 수 있습니다.@()['pcbm';'ejkh';'ifgl';'dnoa']-96
Luis Mendo

@LuisMendo 나는 반환 가치도 수용 가능하다는 것을 알지 못했습니다. 감사합니다!
pajonk

1

스칼라, 52 바이트

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

언 골프 드 :

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

Level River St의 루비 답변 에서 영감을 얻었습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.