Mystery Square

Asked

Viewed 257 times

1

The integers positioned on an Nxn square such that all lines and main diagonal have the same sum.

For example, the square below

2 7 11
9 5 6
4 3 13

is a mysterious square of sum 20, since all lines (2+7+11 = 20, 9+5+6 = 20 and 4+3+13 = 20) and main diagonal (2 + 5 + 13 = 20) have the same sum (20).

Write a program that, given a square, determines if it is mysterious or not and what its sum is (if it is magical).

Entree

The first line contains an integer N. The following lines contain N integers each, separated by exactly one blank.

Exit

Your program should print, in the standard output, a single line with an integer representing the sum of the magic square or -1 if the square is not magic.

PS: I can’t use vector, I can only use repeating structures.

EXAMPLE 1

ENTREE:

3
2 7 11
9 5 6
4 3 13

EXIT:

20

PS: My exit was:

-1

Just follow my code:

int main()
{
    int n, i, j, elem;
    int , soma_linhas = 0, soma_dp = 0;

    scanf("%d", &n);


    //leitura dos elementos
    for(i = 0; i < n; i++){
        for(j = 0; j < n; j++){
            scanf("%d", &elem);
            //somatorio de cada linha
            aux += i;
            soma_linhas = aux;
        }
    }

    //somatorio da diagonal principal 
    for(i = 0; i < n; i++){
        for(j = 0; j < n; j++){
            if(i == j){
                aux += i + j;
                soma_dp = aux;
            }
        }   
    }

    if(soma_linhas == soma_dp)
        printf("%d", soma_linhas);//se for quadrado misterioso tanto faz mostra a linhas ou da diagonal 
    else
        printf("-1");
    return 0;
}

Where am I going wrong?

  • Your input example is not a magic square. The sum of none of the columns is 20. The expected output would be -1.

  • That is the question. It is a mysterious square not a magician. That is why it should be only the sum of the lines and the main diagonal.

2 answers

6


Let’s see those ties:

//leitura dos elementos
for(i = 0; i < n; i++){
    for(j = 0; j < n; j++){
        scanf("%d", &elem);
        //somatorio de cada linha
        aux += i;
        soma_linhas = aux;
    }
}

No matter what happens at the end soma_linhas and aux will have the same value. What will be the value of aux. For a 3x3 square, it will be 0 in the first iteration, 1 in the second (+1) and 3 in the third (+2). However, this is not what he was supposed to do! There is no point in adding up the values of i and disregard the values of elem. You should check the values of elem.

However, even if you use aux += elem;, will still be wrong, as this will end up adding up all the values, and not the values of each line separately.

What you have to do is change this loop so that it adds up the values of each line and from the second line, compare with the value of the previous line.

Note that you are not storing read values anywhere, the variable elem will only hold the last value. Because of this, your loop to check the main diagonal will also not work, as you are only adding up fixed values 0, 1 and 2 and completely ignoring the content of the matrix.

Without storing the entire matrix, it is very difficult to verify that all lines and the main diagonal have the same values. But since you cannot store the values in vectors, you do the following:

  • Use a variable (let’s call it ok) to indicate if the sum of the lines and the main diagonal coincide. Initialize it with 1.

  • Read the first line, adding up all the items (let’s call this a). Store the first element in an auxiliary variable (b).

  • Use a for to read the other lines, adding the elements of each line into another variable c. The element of the main column you add also to the variable b. At the end of each line, check if a == c and change ok to 0 if it is not. Don’t forget to return c to 0 before starting the next line.

  • When finishing the last line, check if a == b and change ok to 0 if it is not.

  • At the end, just check the variable ok.

Something more or less like this:

#include <stdio.h>

int main() {

    int n;
    scanf("%d", &n);

    int elem, a = 0, b = 0, ok = 1;
    for (int i = 0; i < n; i++) {
        int c = 0;
        for (int j = 0; j < n; j++) {
            scanf("%d", &elem);
            if (i == j) b += elem;
            if (i == 0) a += elem;
            c += elem;
        }
        if (a != c) ok = 0;
    }
    if (a != b) ok = 0;

    if (ok) {
        printf("Quadrado misterioso com soma %d.", a);
    } else {
        printf("Não é um quadrado misterioso.");
    }
    return 0;
}

See it working on ideone:

  • I was curious about a practical implementation of the solution without using vectors.

  • @Lacobus Reply edited.

  • @Vitorstafusa: The square columns are not being checked! 2 + 9 + 4 == 15, 7 + 5 + 3 == 15 and 11 + 16 + 13 = 40. (The square of the question is not a magic square!)

  • @Lacobus This is what is expected. Read the statement, it does not say anything about the columns. The mysterious square concerns only the lines and the main diagonal. Maybe you are thinking about the magic square that this yes has to have the sum of rows, columns and both diagonals equal. Every mysterious square is magical, but the opposite is not necessarily true.

  • @Lacobus You can even check the secondary diagonal without using vector, but for the columns, I believe that the use of a vector of accumulators is inevitable. However, since this is to check if the square is mysterious rather than magical, I don’t need this vector because I don’t need the columns.

  • @Victorstafusa on the columns, needs to o(N) extra memory. Independent if you have to validate the lines. Even this gave me an idea of code-golf style issue here xD

Show 1 more comment

3

You do not mention in the question anything about the sum of the columns, according to Wikipedia the definition of a Quadrado Mágico is:

Magic Square is a square table equal to intersection of numbers where the sum of each column, each row and the two diagonals are equal.

inserir a descrição da imagem aqui

Here is a tested and commented solution to check whether a mysterious square is magical or not, check this out:

#include <stdlib.h>
#include <stdio.h>

int eh_magico( int ** quad, int n )
{
    int i = 0, j = 0;
    int x = 0, y = 0;
    int d1 = 0, d2 = 0;

    /* Somatorio das diagonais */
    for( i = 0; i < n; i++ )
    {
        d1 += quad[i][i];
        d2 += quad[n - i - 1][i];
    }

    /* Verifica se diagonais sao iguais */
    if( d1 != d2  )
        return -1;

    for( i = 0; i < n; i++ )
    {
        x = 0;
        y = 0;

        /* Somatorio linha e coluna */
        for( j = 0; j < n; j++ )
        {
            x += quad[i][j];
            y += quad[j][i];
        }

        /* Verifica linha e coluna */
        if( x != d1 || y != d1 )
            return -1;
    }

    /* Eh magico! */
    return d1;
}


int main( void )
{
    int lin, col, dim;
    int ** quadrado_misterioso;

    /* Le dimensoes */
    scanf( "%d", &dim );

    /* Aloca memoria para n linhas */
    quadrado_misterioso = malloc( dim * sizeof(int*) );

    /* Para cada linha */
    for( lin = 0; lin < dim; lin++ )
    {
        /* Aloca memoria para n colunas da linha atual */
        quadrado_misterioso[lin] = malloc( dim * sizeof(int) );

        /* Para cada coluna da linha */
        for( col = 0; col < dim; col++ )
            scanf( "%d", &quadrado_misterioso[lin][col] );
    }

    /* Verifica se eh um quadrado magico */
    printf("%d\n", eh_magico( quadrado_misterioso, dim ) );

    /* Libera memoria ocupada pelo quadrado */
    for( lin = 0; lin < dim; lin++ )
        free(quadrado_misterioso[lin]);
    free(quadrado_misterioso);

    return 0;
}

Testing (n = 3):

3
4   9   2
3   5   7
8   1   6
15

Testing (n = 4):

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

Testing (n = 5):

5
1   23  16  4   21
15  14  7   18  11
24  17  13  9   2
20  8   19  12  6
5   3   10  22  25
65

Testing (n = 3):

3
1   2   3
4   5   6
7   8   9
-1

Testing (n = 3):

3
2   7   11
9   5   6
4   3   13
-1

See working on Ideone.com

  • It is because this question is not caring about the values of the columns. Nor the secondary diagonal. There is actually an editorial error in the question, it should be solved with constant memory, independent of N

Browser other questions tagged

You are not signed in. Login or sign up in order to post.