답변:
l~/{_1fb_,Y${\(_@=\}%:++\z}2*;=
다음과 같은 입력을받습니다.
4 [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
1
매직 스퀘어이면 출력 합니다 0
.
작동 방식 :
l~/ "Evaluates the input and split the array into chunks"
"of size N where N is the first integer";
{ }2* "Run this code block 2 times";
_1fb "Copy the 2D array and calculate sum of each row of copy";
_, "Copy the array containing sum of each row and get"
"its length. This is equal to N";
Y${ }% "Run this code block for each array of the original"
"2D array that we copied from stack";
\(_ "Put the length number to top of stack, decrement and"
"copy that";
@=\ "Take the element at that index from each row and put"
"N back behind at second position in stack";
:+ "Take sum of elements of the array. This is sum of"
"one of the diagonals of the 2D array";
+ "Push diagonal sum to row sum array";
\z "Bring original array to top and transpose columns";
; "At this point, the stack contain 3 arrays:"
" Array with sum of rows and main diagonal,"
" Array with sum of columns and secondary diagonal and"
" The original array. Pop the original array";
= "Check if sum of rows + main diagonal array is equal to ";
"sum of columns + secondary diagonal array";
이것은 더 골프 수 있습니다.
n,l=input()
r=range
print r(1,n*n+1)==sorted(l)*len({sum(l[i::j][:n])for(i,j)in zip(r(n)+r(0,n*n,n)+[0,n-1],[n]*n+[1]*n+[n+1,n-1])})
예제 실행 :
STDIN: 4,[16,3,2,13,5,10,11,8,9,6,7,12,4,15,14,1]
Output: True
다음 두 가지를 확인하십시오.
[1,2,...,n*n].
첫 번째는 이러한 하위 집합에 해당하는 조각을 합하여 확인합니다. 각 행, 열 또는 대각선은 시작 값과 변위로 설명됩니다. 우리는 해당 슬라이스 목록을 가져 와서 n
요소로 자르고 합산합니다. 파이썬의 [start:end:step]
표기법에서 행은 [r*n::1]
, 열은 [c::n]
두 개의 대각선은 [0::n+1]
및 [n-1::n-1]
입니다. 이들은에 2*n+2
의해 생성 된 쌍 의 목록으로 저장 됩니다 zip
.
우리는 합계 세트를 가져와 길이가 1인지 확인합니다. 또한 입력을 정렬하고 그것이 목록인지 확인합니다. [1,2,...,n*n].
실제로, 우리 sorted(l)
는 합계 세트의 길이를 곱하여 항상 하나의 검사로 결합합니다. 합집합의 길이가 1이 아니면 실패합니다.
∧/2=/(+⌿x,⍉x),+/↑1 1∘⍉¨x(⌽x←⎕⍴⍨,⍨⎕)
설명
x←⎕⍴⍨,⍨⎕
입력을 요구하고, 행렬 로 배열 x
⌽
하고, 행렬을 왼쪽에서 오른쪽 으로 뒤집습니다. 행렬을
x(...)
배열로 만듭니다. x
및 그 x
반대 의 행렬
1 1∘⍉¨
각각에 대해 대각선
+/↑
의 숫자를 2 × n 행렬로합니다. 대각선과 행을 합산
⍉x
조옮김 x
x,
과 연결 x
하여 × 2n 행렬을 형성
+⌿
하고 열을 합산
(+⌿x,⍉x),+/↑1 1∘⍉¨x(⌽x←⎕⍴⍨,⍨⎕)
2=/
연속 쌍이 동일한 지 확인
∧/
하고 그 결과를 모두 합산하여 합계 배열을 구성합니다.
d = Diagonal; r = Reverse; i = Input[];
Length@Union[Tr /@ Join[p = Partition[i[[2]], i[[1]]],
t = Transpose@p, {d@p}, {d@t}, {d@r@p}, {d@r@t}]] == 1
다음과 같은 입력을받습니다.
{4,{16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14, 1}}
진실
Input[r=Reverse]
바이트를 저장하기 위해 할 수 있습니다 . #&@@
보다 짧은 바이트 [[1]]
입니다. 또한 Partition
다른 바이트 에 대해 삽입 표기법을 사용할 수도 있습니다 . 그리고 Thread
대신 작동해야합니다 Transpose
. 또는 이 유니 코드 문자 를 사후 수정 연산자로 사용하십시오 (Mathematica는 이 문자 를 전치의 위첨자 T에 사용합니다).
APL 47 32
TwiNight의 우수한 솔루션을 사용하고 약간의 조정을 적용하십시오.
∧/2=/+⌿(1 1∘⍉∘⌽,1 1∘⍉,⍉,⊢)⎕⍴⍨,⍨⎕
설명:
이것은 Dyalog 인터프리터 v14에 도입 된 기능 트레인을 사용합니다. APL은 오른쪽에서 왼쪽으로 실행되고 ⎕는 입력이므로 먼저 치수와 숫자의 벡터를 차례로 입력합니다.
⎕⍴⍨, ⍨⎕는 행렬 NxN을 만듭니다.
그 후 기본적으로 함수 인수는 기본적으로 올바른 인수에 적용되는 일련의 함수 (괄호 사이)입니다. 기능은 다음과 같습니다.
argument 올바른 인수 (매트릭스)를 반환합니다
argument 올바른 인수 행렬을 바꿉니다.
1 1∘⍉ 대각선을 구합니다
1 1∘⍉∘⌽ 반전 된 (가로) 행렬의 대각선을 반환합니다
모든 결과는 ","기능과 연결됩니다
이 시점에서 결과는 열을 합한 (+ ⌿) 행렬입니다. 이 방법으로 얻은 값은 ∧ / 2 = /와 같은지 확인합니다.
나는 오래된 해결책을 여기에 남겨 둘 것이다.
{M←⍺ ⍺⍴⍵⋄d←M=⍉M⋄(⊃≡∪)((+/,+⌿)M),+/∘,¨d(⌽d)ר⊂M}
예를 들어 차원을 왼쪽 인수로, 요소 벡터를 오른쪽 인수로 사용합니다.
4{M←⍺ ⍺⍴⍵⋄d←M=⍉M⋄(⊃≡∪)((+/,+⌿)M),+/∘,¨d(⌽d)ר⊂M}16 3 2 13 5 10 11 8 9 6 7 12 4 15 14 1
1
www.tryapl.org에서 온라인으로 시도 할 수 있습니다
~]:q(/q(/zip+[q()/{(\;}%]+[q((/);(;{(\;}%]+{{+}*}%.&,2<q(2?,{)}%-!*
프롬프트를 사용하여 입력 및 디스플레이 출력을 읽습니다.
FireFox가> 31 인 콘솔에서 테스트 (Array.fill은 매우 새롭습니다)
z=(p=prompt)(n=p()|0).split(' '),u=Array(2*n).fill(e=d=n*(n*n+1)/2),z.map((v,i)=>(r=i/n|0,u[r+n]-=v,u[c=i%n]-=v,d-=v*(r==c),e-=v*(r+c+1==n))),o=!(e|d|u.some(v=>v)),z.sort((a,b)=>a-b||(o=0)),p(o)
덜 골프
n = prompt()|0; // input side length
z = prompt().split(' '); // input list of space separeted numbers
e = d = n*(n*n+1)/2; // Calc sum for each row, column and diagonal
u = Array(2*n).fill(e), // Init check values for n rows and n columns
z.map( (v,i) => { // loop on number array
r = i / n | 0; // row number
c = i % n; // column number
u[r+n] -= v; // subtract current value, if correct it will be 0 at loop end
u[c] -= v;
if (r==c) d -= v; // subtract if diagonal \
if (r+c+1==n) e -=v; // subtract if diagonal /
}),
o=!(e|d|u.some(v=>v)); // true if values for rows, cols and diags are 0
z.sort((a,b)=>a-b||(o=0)); // use sort to verify if there are repeated values in input
alert(o);
&q1l{sM++JcEQCJm.e@bkd_BJqSlQS
여기에서 온라인으로 사용해보십시오 .
&q1l{sM++JcEQCJm.e@bkd_BJqSlQSQ Implicit: Q = evaluated 1st input (contents), E = evaluated 2nd input (side length)
Trailing Q inferred
cEQ Chop E into pieces or length Q
J Store in J
_BJ Pair J with itself with rows reversed
m Map the original and it's reverse, as d, using:
.e d Map each row in d, as b with index k, using:
@bk Get the kth element of b
The result of this map is [[main diagonal], [antidiagonal]]
+J Prepend rows from J
+ CJ Prepend columns from J (transposed J)
sM Sum each
{ Deduplicate
l Length
q1 Is the above equal to 1?
& Logic AND the above with...
SlQ ... is the range [1-length(Q)]...
q ... equal to...
SQ ... sorted(Q)
편집 : 버그를 수정했습니다. @ KevinCruijssen 덕분에 : o)
True
너무 크거나 고유하지 않은 숫자가있는 매직 스퀘어를 출력 합니다. 즉 4
및 [12,26,23,13,21,15,18,20,17,19,22,16,24,14,11,25]
하거나 4
및 [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
출력 둘 다 True
. (거의 모든 기존 답변은 같은 문제가 있지만 4 년 전에 게시 된 이후로 의견에 실수를 바로 잡는 것을 귀찮게하지 않았습니다.)
ô©O®øO®Å\O®Å/O)˜Ë²{¹nLQ*
입력 형식 : 4\n[2,16,13,3,11,5,8,10,7,9,12,6,14,4,1,15]
. 출력 1
/ 0
진실 / 거짓 각각.
온라인으로 시도 하거나 더 많은 테스트 사례를 확인 하십시오 .
설명:
ô # Split the 2nd (implicit) input into parts of a size of the 1st (implicit) input
# i.e. [2,16,13,3,11,5,8,10,7,9,12,6,14,4,1,15] and 4
# → [[2,16,13,3],[11,5,8,10],[7,9,12,6],[14,4,1,15]]
© # Store it in the register (without popping)
O # Take the sum of each row
# i.e. [[2,16,13,3],[11,5,8,10],[7,9,12,6],[14,4,1,15]] → [34,34,34,34]
® # Push the matrix from the register again
ø # Zip/transpose; swapping rows/columns
# i.e. [[2,16,13,3],[11,5,8,10],[7,9,12,6],[14,4,1,15]]
# → [[2,11,7,14],[16,5,9,4],[13,8,12,1],[3,10,6,15]]
O # Sum each inner list again
# i.e. [[2,11,7,14],[16,5,9,4],[13,8,12,1],[3,10,6,15]] → [34,34,34,34]
® # Push the matrix from the register again
Å\ # Get the top-left to bottom-right main diagonal of it
# i.e. [[2,16,13,3],[11,5,8,10],[7,9,12,6],[14,4,1,15]] → [2,5,12,15]
O # Sum it together
# i.e. [2,5,12,15] → 34
® # Push the matrix from the register again
Å/ # Get the top-right to bottom-left main diagonal of it
# i.e. [[2,16,13,3],[11,5,8,10],[7,9,12,6],[14,4,1,15]] → [3,8,9,14]
O # Sum it together
# i.e. [3,8,9,14] → 34
) # Wrap everything on the stack into a list
# → [[34,34,34,34],[34,34,34,34],34,34]
˜ # Flatten this list
# i.e. [[34,34,34,34],[34,34,34,34],34,34] → [34,34,34,34,34,34,34,34,34,34]
Ë # Check if all values are equal to each other
# i.e. [34,34,34,34,34,34,34,34,34,34] → 1 (truthy)
² # Push the second input again
{ # Sort it
# i.e. [2,16,13,3,11,5,8,10,7,9,12,6,14,4,1,15]
# → [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
¹n # Push the first input again, and take its square
# i.e. 4 → 16
L # Create a list in the range [1, squared_input]
# i.e. 16 → [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
Q # Check if the two lists are equal
# i.e. [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
# and [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] → 1 (truthy)
* # Check if both checks are truthy by multiplying them with each other
# i.e. 1 and 1 → 1
# (and output the result implicitly)
(i,j)
단일 번호로보다 효율적으로x
, 복용i=x%C
및j=x/C
일부 대형 충분히위한C
. 나중에 샷을 줄 수 있습니다.