Verificar Magic Square

10

Um quadrado mágico é uma matriz quadrada de números com o lado n constituído pelos números inteiros positivos distintos 1, 2, ..., dispostos de modo que a soma dos n números em qualquer linha horizontal, vertical ou diagonal principal seja sempre a mesmo número, conhecido como constante mágica.

Respostas:

4

CJam, 47 39 35 33 31 bytes

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

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

Saídas `1`se quadrado mágico, `0`caso contrário.

Como funciona :

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

Isso pode ser jogado ainda mais.

Experimente online aqui

6

Caracteres do Python 2: 132

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

Um exemplo de execução:

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

Existem duas coisas para verificar:

1. As somas são as linhas, colunas e diagonais são iguais
2. Os elementos são uma permutação de `[1,2,...,n*n].`

O primeiro é verificado usando somas de fatias correspondentes a esses subconjuntos. Cada linha, coluna ou diagonal é descrita por seu valor inicial e seu deslocamento. Pegamos a fatia correspondente da lista, truncamos em `n`elementos e a somamos. Na `[start:end:step]`notação de Python , linhas são `[r*n::1]`, colunas são `[c::n]`e as duas diagonais são `[0::n+1]`e `[n-1::n-1]`. Eles são armazenados como uma lista de `2*n+2`pares produzidos por `zip`.

Pegamos os conjuntos de somas e verificamos se o comprimento é 1. Também, classificamos a entrada e verificamos se é a lista. `[1,2,...,n*n].`Na verdade, combinamos os dois em um único verificador, multiplicando `sorted(l)`pelo comprimento dos sum-sets, um verificador que sempre falha, a menos que o conjunto de somas tenha comprimento 1.

Percebi que você pode codificar um par de forma `(i,j)`mais eficiente como um único número `x`, levando `i=x%C`e `j=x/C`para alguns grandes o suficiente `C`. Pode tentar depois.
Xnor

5

APL, 35

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

A explicação
`x←⎕⍴⍨,⍨⎕` solicita a entrada, formate-a em uma matriz e atribua a `x`
`⌽`Inverter a matriz da esquerda para a direita
`x(...)`Crie uma matriz de matrizes: `x`e `x`inverta
`1 1∘⍉¨`Para cada uma dessas matrizes, use a diagonal
`+/↑`como uma matriz 2 × n dos números nessas diagonais e somar as linhas

`⍉x`Transponha `x`
`x,`e concatene com `x`para formar uma matriz × 2n
`+⌿`e somar as colunas

`(+⌿x,⍉x),+/↑1 1∘⍉¨x(⌽x←⎕⍴⍨,⍨⎕)`concatenar para formar uma matriz de somas,
`2=/`verificar se pares consecutivos são iguais
`∧/`e AND juntos todos esses resultados

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
``````

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

Certamente, há muitos espaços em branco que podem ser removidos aqui
Beta Decay

Todo o espaço em branco pode ser removido. Deixei lá para facilitar a leitura. E não contei espaço em branco desnecessário.
DavidC

Você pode fazer `Input[r=Reverse]`para salvar um byte. `#&@@`é um byte menor que `[[1]]`. Você provavelmente também pode usar a notação infix `Partition`para outro byte. E `Thread`deve funcionar em vez de `Transpose`. Como alternativa, use esse caractere Unicode como um operador de correção posterior (o Mathematica o usa para T sobrescrito para transposição).
Martin Ender

3

APL 47 32

Usando a excelente solução do TwiNight e aplicando mais alguns ajustes:

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

Explicação:

Isso usa trens funcionais, que foram introduzidos na v14 do intérprete Dyalog. APL é executado da direita para a esquerda, são entradas, então primeiro as dimensões, depois o vetor dos números.

⍨⎕, ⍨⎕ cria a matriz NxN

Depois disso, vem o trem de funções, que são basicamente apenas uma sequência de funções (entre colchetes) aplicada ao argumento correto. As funções são:

⊢ Retorna o argumento correto (que é a matriz)

Transpõe a matriz de argumentos correta

1 1∘⍉ Retorna a diagonal

1 1∘⍉∘⌽ Retorna a diagonal da matriz invertida (horizontalmente)

Neste ponto, o resultado é uma matriz cujas colunas são somadas (+ ⌿). Os valores obtidos dessa maneira são verificados para serem os mesmos com ∧ / 2 = /

Vou deixar minha solução antiga aqui também:

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

toma dimensão como argumento à esquerda, vetor de elementos como argumento à direita, por exemplo:

``````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
``````

Pode ser experimentado online aqui: www.tryapl.org

2

GolfScript 67 ( demo )

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

2

JavaScript (E6) 194

Usando o prompt para ler a entrada e exibir a saída.
Teste no console com FireFox> 31 (o Array.fill é muito novo)

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

Menos golfe

``````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

2

Pitão, 24 30 bytes

``````&q1l{sM++JcEQCJm.e@bkd_BJqSlQS
``````

Experimente online aqui .

``````&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: corrigido um bug, obrigado a @KevinCruijssen por me informar: o)

Isso gera `True`quadrados mágicos com números muito grandes ou nem todos únicos. Ou seja, `4`e `[12,26,23,13,21,15,18,20,17,19,22,16,24,14,11,25]`ou `4`e `[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]`saída ambos `True`. (Resposta Quase todos os existentes têm o mesmo problema, porém, mas uma vez que eles são postados mais de 4 anos atrás, eu não se preocupou em corrigir seus erros em um comentário.)
Kevin Cruijssen

@KevinCruijssen Porra, eu fiquei tão focado em verificar as somas que esqueci dos outros requisitos ... Eu sou tão estúpido #
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)
``````

1

05AB1E , 24 bytes

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

Formato de entrada: `4\n[2,16,13,3,11,5,8,10,7,9,12,6,14,4,1,15]`. Saídas `1`/ `0`para verdade / falsey, respectivamente.

Explicação:

``````ô       # 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)``````
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.