回答:
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
次の2つの点を確認してください。
[1,2,...,n*n].1つ目は、これらのサブセットに対応するスライスの合計を取ることによってチェックされます。各行、列、または対角線は、その開始値と変位によって記述されます。リストに対応するスライスを取得し、n要素に切り捨てて合計します。Pythonのでは[start:end:step]表記、行があり[r*n::1]、列は[c::n]二つの対角線である[0::n+1]と[n-1::n-1]。これらは、2*n+2によって作成されzipたペアのリストとして保存されます。
私たちは、ソート入力し、それがリストされていることを確認し、それはまた、長さ1を持っていることを合計し、チェックのセットを取る[1,2,...,n*n].実際に、我々は乗算することにより、1つのチェックに両方を組み合わせたsorted(l)和集合の長さによって、確認することを常に合計セットの長さが1でない限り失敗します。
∧/2=/(+⌿x,⍉x),+/↑1 1∘⍉¨x(⌽x←⎕⍴⍨,⍨⎕)
説明
x←⎕⍴⍨,⍨⎕への入力のためのプロンプト、行列にそれを形状、および割り当てx
⌽逆転は、マトリックスは、左から右へ
x(...)の行列のアレイを作成しますxとx逆
1 1∘⍉¨それらの行列の各々について、対角取る
+/↑それらの数字の2×N行列を形成します対角線と行の合計
⍉xx
x,次に転置して連結しx、2×2n行列を形成し
+⌿、列を合計します
(+⌿x,⍉x),+/↑1 1∘⍉¨x(⌽x←⎕⍴⍨,⍨⎕)連結して合計の配列を形成し
2=/ます。連続するペアが等しいかどうか
∧/、およびそれらすべての結果をANDで結合するかどうかをチェックします
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バイトより短いです[[1]]。さらにPartition、別のバイトのインフィックス表記法を使用することもできます。のThread代わりに動作するはずですTranspose。または、このUnicode文字を修正後の演算子として使用します(Mathematicaは転置の上付き文字Tに使用します)。
APL 47 32
TwiNightの優れたソリューションを使用し、さらに微調整を適用します。
∧/2=/+⌿(1 1∘⍉∘⌽,1 1∘⍉,⍉,⊢)⎕⍴⍨,⍨⎕
説明:
これは、Dyalogインタープリターのv14で導入された関数列を使用します。APLは右から左に実行され、⎕は入力なので、最初に次元、次に数値のベクトルです。
⎕⍴⍨、⍨⎕は行列NxNを作成します
その後、関数列が続きます。これは、基本的に正しい引数に適用された(括弧の間の)関数のシーケンスです。関数は次のとおりです。
just正しい引数(つまり、行列)を返します
right正しい引数行列を転置します
11∘⍉対角線を返します
11∘⍉∘⌽逆行列(水平)の対角線を返します
すべての結果は関数 "、"と連結されます
この時点で、結果は行列になり、その列が合計されます(+⌿)。この方法で得られた値は、then / 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)1つの数字で、より効率的にx、撮影i=x%Cとj=x/Cいくつかの十分な大きさのためにC。後でそれを試してみるかもしれません。