Sprawdź magiczny kwadrat

10

Magiczne kwadrat jest kwadratem tablicę liczb z boku n składający się z oddzielnych dodatnich liczb 1, 2, ..., n ² usytuowane tak, że suma n ilościach w każdym poziomym, pionowym, albo głównego przekątnej jest zawsze ta sama liczba, znana jako stała magiczna.

Twój program musi wprowadzić, poprzez standardowe wejście, liczbę określającą długość boku kwadratu, a następnie liczby w kwadracie. Żadne liczby nie mogą być użyte więcej niż jeden raz, żadna liczba większa niż n ² nie może być użyta, a wszystkie liczby muszą być większe niż 0. Program musi ustalić, czy ta kombinacja liczb jest magicznym kwadratem.

Wrzlprmft
źródło

Odpowiedzi:

4

CJam, 47 39 35 33 31 bajtów

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

Przyjmuje dane wejściowe jak

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

Wykazuje, 1jeśli magiczny kwadrat, w 0przeciwnym razie.

Jak to działa :

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

Można to dodatkowo pograć w golfa.

Wypróbuj online tutaj

Optymalizator
źródło
6

Python 2: 132 znaki

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

Przykładowy przebieg:

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

Są dwie rzeczy do sprawdzenia:

  1. Sumy są równe wierszom, kolumnom i przekątnym
  2. Elementy są permutacją [1,2,...,n*n].

Pierwszy jest sprawdzany przez pobranie sum plasterków odpowiadających tym podzbiorom. Każdy rząd, kolumna lub przekątna jest opisany przez swoją wartość początkową i przemieszczenie. Bierzemy listę odpowiadającego wycinka, obcinamy do nelementów i sumujemy. W [start:end:step]notacji Pythona wiersze są [r*n::1], kolumny są, [c::n]a dwie przekątne to [0::n+1]i [n-1::n-1]. Są one przechowywane jako lista 2*n+2par wyprodukowanych przez zip.

Bierzemy zestawy sum i sprawdzamy, czy ma długość 1. Ponadto sortujemy dane wejściowe i sprawdzamy, czy jest to lista. [1,2,...,n*n].Właściwie łączymy oba w jedno sprawdzenie, mnożąc sorted(l)przez długość zestawów sum, sprawdzenie, które zawsze kończy się niepowodzeniem, chyba że zestaw sum ma długość 1.

xnor
źródło
Uświadomiłem sobie, że możesz (i,j)efektywniej zakodować parę jako jedną liczbę x, biorąc i=x%Ci j=x/Cdla niektórych wystarczająco dużych C. Może spróbuję później.
xnor
5

APL, 35

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

Objaśnienie
x←⎕⍴⍨,⍨⎕ monituje o wprowadzenie danych, ukształtowanie ich w macierz i przypisanie do x
Odwraca macierz od lewej do prawej
x(...)Utwórz tablicę macierzy: xi xodwróć
1 1∘⍉¨Dla każdej z tych macierzy weź przekątną
+/↑2 × n macierzy liczb na tych przekątne i zsumuj rzędy

⍉xTransponuj, x
x,a następnie połącz z, xaby utworzyć macierz × 2n
+⌿i zsumuj kolumny

(+⌿x,⍉x),+/↑1 1∘⍉¨x(⌽x←⎕⍴⍨,⍨⎕)konkatenuj, aby utworzyć tablicę sum,
2=/sprawdź, czy kolejne pary są równe
∧/i ORAZ razem wszystkie te wyniki

TwiNight
źródło
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

Pobiera dane wejściowe, takie jak

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

Prawdziwe

DavidC
źródło
Z pewnością można tu usunąć wiele białych znaków
rozpad Beta
Całą białą przestrzeń można usunąć. Zostawiłem to dla czytelności. I nie liczyłem niepotrzebnej białej przestrzeni.
DavidC
Możesz zrobić, Input[r=Reverse]aby zapisać bajt. #&@@jest bajtem krótszym niż [[1]]. Prawdopodobnie możesz dodatkowo użyć notacji infix Partitiondla innego bajtu. I Threadpowinien działać zamiast Transpose. Alternatywnie, użyj tego znaku Unicode jako operatora post fix (Mathematica używa go dla indeksu górnego T do transpozycji).
Martin Ender
3

APL 47 32

Korzystając z doskonałego rozwiązania TwiNight i wprowadzając dodatkowe poprawki:

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

Wyjaśnienie:

Wykorzystuje to ciągi funkcji, które zostały wprowadzone w wersji 14 interpretera Dyalog. APL jest wykonywany od prawej do lewej, ⎕ są wejściami, więc najpierw wymiary, a następnie wektor liczb.

⎕⍴⍨, ⍨⎕ tworzy macierz NxN

Potem następuje ciąg funkcji, które są w zasadzie sekwencją funkcji (między nawiasami) zastosowanych do właściwego argumentu. Funkcje to:

⊢ Zwraca właściwy argument (czyli macierz)

Oses Transponuje właściwą macierz argumentów

1 1∘⍉ Zwraca przekątną

1 1∘⍉∘⌽ Zwraca przekątną odwróconej (poziomo) macierzy

Wszystkie wyniki są łączone z funkcją „,”

W tym momencie wynikiem jest macierz, której kolumny są następnie sumowane (+ ⌿). Uzyskane w ten sposób wartości są następnie sprawdzane, aby były takie same przy ∧ / 2 = /

Zostawię tu również moje stare rozwiązanie:

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

przyjmuje wymiar jako lewy argument, wektor elementów jako prawy argument, na przykład:

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

Można wypróbować online tutaj: www.tryapl.org

Moris Zucca
źródło
2

GolfScript 67 ( wersja demonstracyjna )

~]:q(/q(/zip+[q()/{(\;}%]+[q((/);(;{(\;}%]+{{+}*}%.&,2<q(2?,{)}%-!*
Cristian Lupascu
źródło
2

JavaScript (E6) 194

Za pomocą zachęty do odczytu danych wejściowych i wyjściowych.
Test w konsoli z FireFox> 31 (Array.fill jest bardzo nowy)

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)

Mniej golfa

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
źródło
2

Pyth, 24 30 bajtów

&q1l{sM++JcEQCJm.e@bkd_BJqSlQS

Wypróbuj online tutaj .

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

Edycja: naprawiono błąd, dzięki @KevinCruijssen za poinformowanie mnie o: o)

Sok
źródło
Daje to Truemagiczne kwadraty z liczbami, które są zbyt duże lub nie wszystkie są unikalne. Ie 4i [12,26,23,13,21,15,18,20,17,19,22,16,24,14,11,25]lub 4i [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]wyjście zarówno True. (Prawie wszystkie istniejące odpowiedzi mają ten sam problem, ale ponieważ zostały opublikowane ponad 4 lata temu, nie zadałem sobie trudu, aby poprawić swoje błędy w komentarzu.)
Kevin Cruijssen
@KevinCruijssen Cholera, tak bardzo skoncentrowałem się na weryfikacji sum, że zapomniałem o innych wymaganiach ... Jestem takim narkomanem
Sok
1

LUA 186 znaków

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)
jawo
źródło
1

05AB1E , 24 bajty

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

Format wejściowy: 4\n[2,16,13,3,11,5,8,10,7,9,12,6,14,4,1,15]. Wyjścia 1/ odpowiednio 0dla truey / falsey.

Wypróbuj online lub sprawdź więcej przypadków testowych .

Wyjaśnienie:

ô       # 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
źródło