Überprüfen Sie das Magic Square

10

Ein magisches Quadrat ist eine quadratische Anordnung von Zahlen mit n Seite , bestehend aus den verschiedenen positiven ganzen Zahlen 1, 2, ..., n ² so angeordnet, dass die Summe der n Zahlen in irgendeiner horizontalen, vertikalen oder diagonalen Hauptleitung ist immer die gleiche Zahl, die als magische Konstante bekannt ist.

Ihr Programm muss über std-in eine Zahl eingeben, die die Länge der Seite Ihres Quadrats angibt, und dann die Zahlen im Quadrat. Keine Zahlen mehr als einmal verwendet werden, keine Zahl größer als n ² verwendet werden kann, und alle Zahlen müssen größer als 0 sein muss das Programm bestimmen , ob diese Kombination von Zahlen ist ein magisches Quadrat.

Wrzlprmft
quelle

Antworten:

4

CJam, 47 39 35 33 31 Bytes

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

Nimmt Eingaben wie

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

Gibt sonst ein 1magisches Quadrat aus 0.

Wie es funktioniert :

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

Dies kann weiter Golf gespielt werden.

Probieren Sie es hier online aus

Optimierer
quelle
6

Python 2: 132 Zeichen

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

Ein Beispiellauf:

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

Das sind zwei Dinge zu überprüfen:

  1. Die Summen sind die Zeilen, Spalten und Diagonalen, die alle gleich sind
  2. Die Elemente sind eine Permutation von [1,2,...,n*n].

Die erste wird überprüft, indem Summen von Slices genommen werden, die diesen Teilmengen entsprechen. Jede Zeile, Spalte oder Diagonale wird durch ihren Startwert und ihre Verschiebung beschrieben. Wir nehmen das entsprechende Slice der Liste, schneiden es auf nElemente ab und summieren es. In Pythons [start:end:step]Notation sind Zeilen [r*n::1], Spalten [c::n]und die beiden Diagonalen [0::n+1]und [n-1::n-1]. Diese werden als Liste von 2*n+2Paaren gespeichert, die von erstellt wurden zip.

Wir nehmen die Summensätze und prüfen, ob sie die Länge 1 haben. Außerdem sortieren wir die Eingabe und prüfen, ob es sich um die Liste handelt. [1,2,...,n*n].Tatsächlich kombinieren wir beide zu einer Prüfung, indem wir sie mit der Länge der Summenmengen multiplizieren sorted(l), eine Prüfung, die immer erfolgt schlägt fehl, es sei denn, der Summensatz hat die Länge 1.

xnor
quelle
Mir wurde klar, dass Sie ein Paar (i,j)effizienter als eine einzelne Zahl codieren können x, indem Sie i=x%Cund j=x/Cfür einige, die groß genug sind C. Könnte das später versuchen.
xnor
5

APL, 35

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

Erläuterung
x←⎕⍴⍨,⍨⎕ fordert zur Eingabe auf, x
formt sie zu einer Matrix und weist sie zu. Umkehrt die Matrix von links nach rechts.
x(...)Erstellen Sie ein Array von Matrizen: xund xkehren
1 1∘⍉¨Sie um. Nehmen Sie für jede dieser Matrizen die Diagonale
+/↑einer 2 × n-Matrix der Zahlen auf diesen an Diagonalen und summieren die Reihen

⍉xTransponieren Sie x
x,dann verketten mit x, um eine × 2n-Matrix zu bilden
+⌿und die Spalten zu summieren

(+⌿x,⍉x),+/↑1 1∘⍉¨x(⌽x←⎕⍴⍨,⍨⎕)verketten, um ein Array der Summen zu bilden.
2=/Prüfen Sie, ob aufeinanderfolgende Paare gleich sind
∧/und alle diese Ergebnisse UND-verknüpfen

TwiNight
quelle
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

Nimmt Eingaben wie z

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

Wahr

DavidC
quelle
Sicher gibt es eine Menge Leerzeichen, die hier entfernt werden können
Beta Decay
Der gesamte Leerraum kann entfernt werden. Ich habe es dort zur besseren Lesbarkeit gelassen. Und ich habe keine unnötigen Leerzeichen gezählt.
DavidC
Sie können Input[r=Reverse]ein Byte speichern. #&@@ist ein Byte kürzer als [[1]]. Sie können wahrscheinlich zusätzlich die Infix-Notation Partitionfür ein anderes Byte verwenden. Und Threadsollte statt funktionieren Transpose. Alternativ können Sie dieses Unicode-Zeichen als Post-Fix-Operator verwenden (Mathematica verwendet es für hochgestelltes T für die Transponierung).
Martin Ender
3

APL 47 32

Verwenden Sie die hervorragende Lösung von TwiNight und wenden Sie weitere Optimierungen an:

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

Erläuterung:

Hierbei werden Funktionszüge verwendet, die in Version 14 des Dyalog-Interpreters eingeführt wurden. APL wird von rechts nach links ausgeführt, ⎕s sind Eingaben, also zuerst die Dimensionen, dann der Vektor der Zahlen.

⎕⍴⍨, ⍨⎕ erzeugt die Matrix NxN

Danach folgt der Funktionszug, bei dem es sich im Grunde nur um eine Folge von Funktionen (in Klammern) handelt, die auf das richtige Argument angewendet werden. Die Funktionen sind:

⊢ Gibt genau das richtige Argument zurück (das ist die Matrix)

⍉ Transponiert die richtige Argumentmatrix

1 1∘⍉ Gibt die Diagonale zurück

1 1∘⍉∘⌽ Gibt die Diagonale der umgekehrten (horizontalen) Matrix zurück

Alle Ergebnisse werden mit der Funktion "," verkettet.

Zu diesem Zeitpunkt ist das Ergebnis eine Matrix, deren Spalten dann summiert werden (+ ⌿). Die auf diese Weise erhaltenen Werte werden dann mit ∧ / 2 = / auf die gleichen Werte überprüft

Ich werde meine alte Lösung auch hier lassen:

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

Nimmt die Dimension als linkes Argument, den Vektor der Elemente als rechtes Argument, zum Beispiel:

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

Kann hier online ausprobiert werden: www.tryapl.org

Moris Zucca
quelle
2

GolfScript 67 ( Demo )

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

JavaScript (E6) 194

Verwenden der Eingabeaufforderung zum Lesen der Eingabe und Anzeigen der Ausgabe.
Test in der Konsole mit FireFox> 31 (Array.fill ist sehr neu)

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)

Weniger Golf gespielt

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
quelle
2

Pyth, 24 30 Bytes

&q1l{sM++JcEQCJm.e@bkd_BJqSlQS

Probieren Sie es hier online aus .

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

Bearbeiten: Fehler behoben, danke an @KevinCruijssen, der mich informiert hat: o)

Sok
quelle
Dies gibt Truefür magische Quadrate mit Zahlen aus, die zu groß oder nicht alle eindeutig sind. Dh 4und [12,26,23,13,21,15,18,20,17,19,22,16,24,14,11,25]oder 4und [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]geben beide aus True. (Fast alle vorhandenen Antworten haben das gleiche Problem, aber da sie vor über 4 Jahren veröffentlicht wurden, habe ich mich nicht darum
gekümmert,
@ KevinCruijssen Verdammt, ich habe mich so darauf konzentriert, die Summen zu überprüfen, dass ich die anderen Anforderungen vergessen habe ... Ich bin so ein Trottel
Sok
1

LUA 186 Zeichen

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)
Sempie
quelle
1

05AB1E , 24 Bytes

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

Eingabeformat : 4\n[2,16,13,3,11,5,8,10,7,9,12,6,14,4,1,15]. Ausgänge 1/ 0für wahrheitsgemäß / falsch.

Probieren Sie es online aus oder überprüfen Sie weitere Testfälle .

Erläuterung:

ô       # 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
quelle