Vérifiez Magic Square

10

Un carré magique est un tableau carré de nombres dont le côté n est composé des entiers positifs distincts 1, 2, ..., n ² disposés de telle sorte que la somme des n nombres dans toute ligne diagonale horizontale, verticale ou principale soit toujours la même nombre, qui est connu comme la constante magique.

Votre programme doit saisir, via std-in, un nombre spécifiant la longueur du côté de votre carré, puis les nombres du carré. Aucun nombre ne peut être utilisé plus d'une fois, aucun nombre supérieur à n ² ne peut être utilisé et tous les nombres doivent être supérieurs à 0. Le programme doit déterminer si cette combinaison de nombres est un carré magique.

Wrzlprmft
la source

Réponses:

4

CJam, 47 39 35 33 31 octets

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

Prend l'entrée comme

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

Sorties 1si carré magique, 0sinon.

Comment ça marche :

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

Cela peut être joué plus loin.

Essayez-le en ligne ici

Optimiseur
la source
6

Python 2: 132 caractères

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

Un exemple de course:

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

Il y a deux choses à vérifier:

  1. Les sommes sont les lignes, les colonnes et les diagonales sont toutes égales
  2. Les éléments sont une permutation de [1,2,...,n*n].

La première est vérifiée en prenant des sommes de tranches correspondant à ces sous-ensembles. Chaque ligne, colonne ou diagonale est décrite par sa valeur de départ et son déplacement. Nous prenons la liste correspondant à la tranche, la tronquons aux néléments et la sommons. Dans la [start:end:step]notation Python , les lignes sont [r*n::1], les colonnes sont [c::n]et les deux diagonales sont [0::n+1]et [n-1::n-1]. Ceux-ci sont stockés sous forme de liste de 2*n+2paires produites par zip.

Nous prenons les ensembles de sommes et vérifions qu'il a une longueur 1. De plus, nous trions l'entrée et vérifions que c'est la liste [1,2,...,n*n].En fait, nous combinons les deux en un seul contrôle en multipliant sorted(l)par la longueur des ensembles de sommes, un contrôle qui échoue sauf si l'ensemble de somme a la longueur 1.

xnor
la source
J'ai réalisé que vous pouvez encoder une paire (i,j)plus efficacement en un seul numéro x, en prenant i=x%Cet j=x/Cpour certains assez gros C. Pourrait donner un coup de feu plus tard.
xnor
5

APL, 35

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

Une explication vous
x←⎕⍴⍨,⍨⎕ invite à entrer, à la façonner en une matrice et à affecter à x
Inverse la matrice de gauche à droite
x(...)Créez un tableau de matrices: xet xinversez
1 1∘⍉¨Pour chacune de ces matrices, prenez la
+/↑forme diagonale d' une matrice 2 × n des nombres sur ces diagonales et additionner les lignes

⍉xTransposer x
x,puis concaténer avec xpour former une matrice × 2n
+⌿et additionner les colonnes

(+⌿x,⍉x),+/↑1 1∘⍉¨x(⌽x←⎕⍴⍨,⍨⎕)concaténer pour former un tableau des sommes
2=/vérifier si les paires consécutives sont égales
∧/ET ET ensemble tous ces résultats

TwiNight
la source
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

Prend des informations telles que

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

Vrai

DavidC
la source
Il y a sûrement beaucoup d'espaces qui peuvent être supprimés ici
Beta Decay
Tous les espaces blancs peuvent être supprimés. Je l'ai laissé là pour la lisibilité. Et je n'ai pas compté d'espace blanc inutile.
DavidC
Vous pouvez faire Input[r=Reverse]pour enregistrer un octet. #&@@est un octet plus court que [[1]]. Vous pouvez probablement également utiliser la notation infixe Partitionpour un autre octet. Et Threaddevrait fonctionner au lieu de Transpose. Vous pouvez également utiliser ce caractère Unicode comme opérateur post-correction (Mathematica l'utilise en exposant T pour la transposition).
Martin Ender
3

APL 47 32

Utilisation de l'excellente solution de TwiNight et application de quelques ajustements supplémentaires:

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

Explication:

Cela utilise des trains de fonctions, qui ont été introduits dans la version 14 de l'interpréteur Dyalog. APL est exécuté de droite à gauche, les ⎕ sont des entrées, donc d'abord les dimensions, puis le vecteur des nombres.

⎕⍴⍨, ⍨⎕ crée la matrice NxN

Après cela vient le train de fonctions qui sont fondamentalement juste une séquence de fonctions (entre crochets) appliquées au bon argument. Les fonctions sont les suivantes:

⊢ Renvoie l'argument juste à droite (c'est la matrice)

⍉ Transpose la bonne matrice d'arguments

1 1∘⍉ Renvoie la diagonale

1 1∘⍉∘⌽ Renvoie la diagonale de la matrice inversée (horizontalement)

Tous les résultats sont concaténés avec la fonction ","

À ce stade, le résultat est une matrice dont les colonnes sont ensuite additionnées (+ ⌿). Les valeurs ainsi obtenues sont ensuite vérifiées pour être les mêmes avec ∧ / 2 = /

Je vais laisser mon ancienne solution ici aussi:

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

prend dimension comme argument de gauche, vecteur d'éléments comme argument de droite, par exemple:

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

Peut être essayé en ligne ici: www.tryapl.org

Moris Zucca
la source
2

GolfScript 67 ( démo )

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

JavaScript (E6) 194

Utilisation de l'invite pour lire l'entrée et afficher la sortie.
Test en console avec FireFox> 31 (Array.fill est très nouveau)

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)

Moins 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
la source
2

Pyth, 24 30 octets

&q1l{sM++JcEQCJm.e@bkd_BJqSlQS

Essayez-le en ligne ici .

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

Edit: correction d'un bug, merci à @KevinCruijssen de m'avoir prévenu: o)

Sok
la source
Cela génère Truedes carrés magiques avec des nombres trop grands ou pas tous uniques. Ie 4et [12,26,23,13,21,15,18,20,17,19,22,16,24,14,11,25]ou ou 4et [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]les deux True. (Presque toutes les réponses existantes ont le même problème, mais puisqu'elles sont publiées il y a plus de 4 ans, je n'ai pas pris la peine de corriger leurs erreurs dans un commentaire.)
Kevin Cruijssen
@KevinCruijssen Damn, je me suis tellement concentré sur la vérification des sommes que j'ai oublié les autres exigences ... Je suis tellement dope
Sok
1

LUA 186 caractères

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
la source
1

05AB1E , 24 octets

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

Format d' entrée: 4\n[2,16,13,3,11,5,8,10,7,9,12,6,14,4,1,15]. Sorties 1/ 0pour vérité / falsey respectivement.

Essayez-le en ligne ou vérifiez d'autres cas de test .

Explication:

ô       # 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
la source