Verifikasi Magic Square

10

Sebuah persegi sihir adalah array persegi angka dengan sisi n terdiri dari bilangan bulat positif yang berbeda 1, 2, ..., n ² diatur sedemikian rupa sehingga jumlah dari n angka dalam setiap horisontal, vertikal, atau jalur utama diagonal selalu nomor yang sama, yang dikenal sebagai konstanta sihir.

Program Anda harus memasukkan, melalui std-in, angka yang menentukan panjang sisi bujur sangkar Anda, kemudian angka-angka di bujur sangkar. Tidak ada nomor dapat digunakan lebih dari sekali, tidak ada nomor lebih besar dari n ² dapat digunakan, dan semua nomor harus lebih besar dari 0. Program harus menentukan apakah yang kombinasi angka adalah sihir persegi.

Wrzlprmft
sumber

Jawaban:

4

CJam, 47 39 35 33 31 byte

l~/{_1fb_,Y${\(_@=\}%:++\z}2*;=

Mengambil input seperti

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

Keluaran 1jika kotak ajaib, 0jika tidak.

Cara kerjanya :

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";

Ini bisa bermain golf lebih lanjut.

Cobalah online di sini

Pengoptimal
sumber
6

Python 2: 132 karakter

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])})

Contoh dijalankan:

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

Dua hal yang perlu diperiksa:

  1. Jumlahnya adalah baris, kolom, dan diagonal semuanya sama
  2. Elemen-elemen adalah permutasi dari [1,2,...,n*n].

Yang pertama diperiksa dengan mengambil jumlah irisan yang sesuai dengan himpunan bagian ini. Setiap baris, kolom, atau diagonal dijelaskan oleh nilai awal dan perpindahannya. Kami mengambil daftar irisan yang sesuai, memotong nelemen, dan menjumlahkannya. Dalam [start:end:step]notasi Python , baris adalah [r*n::1], kolom adalah [c::n]dan dua diagonal adalah [0::n+1]dan [n-1::n-1]. Ini disimpan sebagai daftar 2*n+2pasangan yang diproduksi oleh zip.

Kami mengambil set jumlah dan memeriksa bahwa itu memiliki panjang 1. Juga, kami mengurutkan input dan memeriksa apakah itu daftar. [1,2,...,n*n].Sebenarnya, kami menggabungkan keduanya menjadi satu cek dengan mengalikan sorted(l)dengan panjang jumlah, sebuah cek yang selalu gagal kecuali jumlah-set memiliki panjang 1.

Tidak
sumber
Saya menyadari bahwa Anda dapat menyandikan pasangan secara (i,j)lebih efisien sebagai satu nomor x, mengambil i=x%Cdan j=x/Cuntuk beberapa yang cukup besar C. Mungkin bisa mencobanya nanti.
xnor
5

APL, 35

∧/2=/(+⌿x,⍉x),+/↑1 1∘⍉¨x(⌽x←⎕⍴⍨,⍨⎕)

Penjelasan
x←⎕⍴⍨,⍨⎕ meminta input, membentuknya menjadi matriks, dan menetapkan untuk x
Membalikkan matriks kiri-ke-kanan
x(...)Buat array matriks: xdan xmembalikkan
1 1∘⍉¨Untuk masing-masing matriks, ambil
+/↑bentuk diagonal 2 × n matriks dari angka-angka pada mereka diagonal dan jumlah baris

⍉xTranspose x
x,lalu gabungkan dengan xuntuk membentuk matriks × 2n
+⌿dan jumlah kolom

(+⌿x,⍉x),+/↑1 1∘⍉¨x(⌽x←⎕⍴⍨,⍨⎕)menyatukan untuk membentuk array dari jumlah
2=/memeriksa apakah pasangan berturut-turut sama
∧/dan DAN bersama-sama semua hasil itu

TwiNight
sumber
3

Mathematica 128 125

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

Mengambil input seperti

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

Benar

DavidC
sumber
Tentunya ada banyak ruang putih yang dapat dihapus di sini
Beta Decay
Semua ruang putih bisa dihilangkan. Saya meninggalkannya di sana untuk dibaca. Dan saya tidak menghitung ruang putih yang tidak perlu.
DavidC
Anda dapat melakukannya Input[r=Reverse]untuk menghemat satu byte. #&@@byte lebih pendek dari [[1]]. Anda juga dapat menggunakan notasi infiks Partitionuntuk byte lain. Dan Threadseharusnya bekerja Transpose. Atau, gunakan karakter Unicode ini sebagai operator perbaikan pos (Mathematica menggunakannya untuk superscript T untuk transpose).
Martin Ender
3

APL 47 32

Menggunakan solusi hebat TwiNight dan menerapkan beberapa penyesuaian lainnya:

∧/2=/+⌿(1 1∘⍉∘⌽,1 1∘⍉,⍉,⊢)⎕⍴⍨,⍨⎕

Penjelasan:

Ini menggunakan kereta fungsi, yang diperkenalkan pada v14 dari juru bahasa Dyalog. APL dijalankan dari kanan ke kiri, ⎕ adalah input, jadi pertama dimensi, lalu vektor angka.

⎕⍴⍨, ⍨⎕ menciptakan matriks NxN

Setelah itu muncul function train yang pada dasarnya hanya urutan fungsi (antara kurung) yang diterapkan pada argumen yang benar. Fungsinya adalah:

⊢ Mengembalikan argumen yang tepat (yaitu matriks)

⍉ Mengubah matriks argumen yang tepat

1 1∘⍉ Mengembalikan diagonal

1 1∘⍉∘⌽ Mengembalikan diagonal dari matriks yang terbalik (horizontal)

Semua hasil digabungkan dengan fungsi ","

Pada titik ini, hasilnya adalah matriks yang kolomnya kemudian dijumlahkan (+ ⌿). Nilai yang diperoleh dengan cara ini kemudian diperiksa agar sama dengan ∧ / 2 = /

Saya akan meninggalkan solusi lama saya di sini juga:

{M←⍺ ⍺⍴⍵⋄d←M=⍉M⋄(⊃≡∪)((+/,+⌿)M),+/∘,¨d(⌽d)ר⊂M}

mengambil dimensi sebagai argumen kiri, vektor elemen sebagai argumen kanan, misalnya:

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

Dapat dicoba online di sini: www.tryapl.org

Moris Zucca
sumber
2

GolfScript 67 ( demo )

~]:q(/q(/zip+[q()/{(\;}%]+[q((/);(;{(\;}%]+{{+}*}%.&,2<q(2?,{)}%-!*
Cristian Lupascu
sumber
2

JavaScript (E6) 194

Menggunakan prompt untuk membaca input dan menampilkan output.
Tes di konsol dengan FireFox> 31 (Array.fill sangat baru)

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)

Kurang golf

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);
edc65
sumber
2

Pyth, 24 30 byte

&q1l{sM++JcEQCJm.e@bkd_BJqSlQS

Cobalah online di sini .

&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)

Sunting: memperbaiki bug, terima kasih kepada @KevinCruijssen karena memberi tahu saya: o)

Sok
sumber
Ini menghasilkan Truekotak ajaib dengan angka yang terlalu besar, atau tidak semuanya unik. Yaitu 4dan [12,26,23,13,21,15,18,20,17,19,22,16,24,14,11,25]atau 4dan [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]output keduanya True. (Hampir semua jawaban yang ada memiliki masalah yang sama, tetapi karena mereka diposting lebih dari 4 tahun yang lalu saya tidak repot-repot memperbaiki kesalahan mereka dalam komentar.)
Kevin Cruijssen
@KevinCruijssen Sialan, saya menjadi begitu fokus pada memverifikasi jumlah yang saya lupa tentang persyaratan lain ... Saya seperti orang bodoh
Sok
1

LUA 186 Chars

s=io.read(1)v=io.read(2)d=0 r=0 for i=1,#s do t=0 for j = 1, #s do t=t+s[i][j]end d=d+s[i][i] r=r+s[i][#s-i+1]if t ~= v then o=true end end if d~=v and r~= v then o=true end print(not o)
rahang
sumber
1

05AB1E , 24 byte

ô©O®øO®Å\O®Å/O)˜Ë²{¹nLQ*

Format input: 4\n[2,16,13,3,11,5,8,10,7,9,12,6,14,4,1,15]. Keluaran 1/ 0untuk kebenaran / kepalsuan masing-masing.

Cobalah secara online atau verifikasi beberapa kasus uji lagi .

Penjelasan:

ô       # 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)
Kevin Cruijssen
sumber