Ir ao conteúdo

Posts recomendados

Postado

Estou com uma atividade, que pede que desenvolva um código que me retorne um quadrado mágico. Um quadrado mágico é uma matriz quadrática (2x2,3x3) em que as somas de cada uma das suas linhas, colunas e diagonais, resultem no mesmo valor. Nesse código, eu gero uma lista de números até o tam² da matriz, e em seguida eu embaralho ela, porque os números não podem se repetir. Porém só funciona com uma matriz 3x3, quando eu tento com uma matriz maior, 4x4, 5x5 e afins, o código faz a impressão de números aleatórios. Não sei mais onde eu possa estar errando. Se alguém puder me explicar mais sobre. Segue meu código:
 

#include <stdlib.h>
#include <time.h>
#include <string.h>


void quadrado_magico(int **matriz, int linhas, int colunas,int valor_maximo, int numeros[], int *somalinhas, int *somacolunas, int *somadiagonalPrincipal, int *somadiagonalSecundaria){
    
    int soma_numeros, soma_esperada;
    int eh_quadrado = 0; //valor boleano = 1 pra true e 0 para false
    int tentativas = 0;
    
    while (eh_quadrado != 1 && tentativas < 5000){
        
        //Gerar uma lista de numeros de n ate n
        soma_numeros = 0;
        for (int i = 0; i < valor_maximo; i++){
            numeros[i] = i + 1;
            soma_numeros += numeros[i];
        }
        
        soma_esperada = soma_numeros / linhas;
        
        //Embaralhar os numeros de forma aleatoria
        for (int i = valor_maximo - 1; i > 0; i--){
            int j = rand()%(valor_maximo);
            
            int aux = numeros[i];
            numeros[i] = numeros[j];
            numeros[j] = aux;
            
        }
        
        for (int i = 0; i < linhas; i++){
            for (int j = 0; j < colunas; j++){
                matriz[i][j] = numeros[i * linhas + j];
            }
        }
        
        //inicializar com 0
        for (int i = 0; i < linhas; i++){
            somalinhas[i] = 0;
            somacolunas[i] = 0;
        }
        
        //soma linhas e colunas
        for  (int i = 0; i < linhas; i++){
            for (int j = 0; j < colunas;j++){
                somalinhas[i] += matriz[i][j];
                somacolunas[j] += matriz[i][j];
            }
        }
        
        *somadiagonalPrincipal = 0;
        *somadiagonalSecundaria = 0;
        
        //somas das diagonais
        for(int i = 0; i < linhas; i++){
            *somadiagonalPrincipal += matriz[i][i];
            *somadiagonalSecundaria += matriz[i][linhas - 1 - i];
        }
        
        //assumimos que e um quadrado magico
        eh_quadrado = 1;
        
        
        for (int i = 0; i < linhas; i++){
            for (int j = 0; j < colunas; j++){
                if (somalinhas[i] != soma_esperada || somacolunas[i] != soma_esperada || 
                    *somadiagonalPrincipal  != soma_esperada || *somadiagonalSecundaria != soma_esperada){
                    eh_quadrado = 0;
                    break;
                }
            }
        }
        tentativas++;
    }
    
}
void impressao (int **matriz, int linhas, int colunas, int numeros[], int *somalinhas, int *somacolunas, int *somadiagonalPrincipal, int *somadiagonalSecundaria){
    
    char choice_soma[4], choice_array[4];
    printf("Você deseja ver a matriz resultante?(Sim/Não)\n");
    scanf("%s", choice_array);
    if (strcmp(choice_array, "Sim") == 0 || strcmp(choice_array, "sim") == 0){
        printf("[");
        for (int i = 0; i < linhas; i++){
            for (int j = 0; j < colunas; j++){
                printf("%2d", matriz[i][j]);
                
            }
            if (i < linhas - 1){
                printf("\n");
            }
        }
        printf("]\n");
    }
    printf("\nVocê deseja ver o resultado das somas?(Sim/Não)\n");
    scanf("%s", choice_soma);
    if (strcmp(choice_soma, "Sim") == 0 || strcmp(choice_soma, "sim") == 0){
        for (int i = 0; i < linhas; i++) {
          printf("A soma da %dº Linha e: %d\n", i+1, somalinhas[i]);
        }
        printf("\n");
        for (int j = 0; j < colunas; j++) {
          printf("A soma da %dº Coluna e: %d\n", j+1, somacolunas[j]);
        }
        
        printf("\n\n");
        printf("Diagonal Principal: %d\n", *somadiagonalPrincipal);
        printf("Diagonal Secundaria: %d", *somadiagonalSecundaria);
    }
}

int main(){
    srand(time(0));// Sempre gerar outro numero
    printf("Instruções: ");
    printf("Um quadrado magico, é uma matriz de tamanhos iguais,(o mesmo numero"
    "de linhas e colunas) em que a soma de suas linhas, colunas e diagonais sejam iguais.");
    printf(" Esse codigo vai gerar uma matriz de tamanho inserida pelo usuario, onde os numeros não"
    "não se repetem, e que seja um quadrado magico.");
    printf("\nVamos lá...\n\n");
    
    int tamanho;
    
    printf("Insira o tamanho da matriz quadrada: ");
    scanf("%d", &tamanho);
    
    int valor_maximo = (tamanho * tamanho);
    
    
    int numeros[valor_maximo];

    int linhas = tamanho, colunas = tamanho;
    
    int **matriz = (int **) malloc(linhas * sizeof(int *));
    for (int i = 0; i < linhas; i++){
        matriz[i] = (int *) malloc (colunas * sizeof(int ));
    }
    
    int *somal = (int *) malloc (tamanho * sizeof(int));
    int *somac = (int *) malloc (tamanho * sizeof(int));
    int *somaDP = (int *) malloc (tamanho * sizeof(int));
    int *somaSC = (int *) malloc (tamanho * sizeof(int));
 
    quadrado_magico(matriz, linhas, colunas,valor_maximo, numeros, somal, somac, somaDP, somaSC);
    impressao(matriz, linhas, colunas, numeros, somal, somac, somaDP, somaSC);
    
    
    
    
    
    for (int i = 0; i < linhas; i++){
        free(matriz[i]);
    }
    
    free(matriz);
    free(somal);
    free(somac);
    free(somaDP);
    free(somaSC);
    
    return 0;
}

Obs: Se eu trocar a condição do while de && para || os resultados também são modificados.

  • Amei 1
Postado

@DaviFonsecx @DaviFonsecx

Em 18/10/2024 às 10:38, DaviFonsecx disse:

Obs: Se eu trocar a condição do while de && para || os resultados também são modificados.

sim ,  é lógico que o resultado será outro pois esse símbolo "&&" significa "AND" e é usado para inclusão ( um e outro)  , enquanto esse "||" é "OU" e significa exclusão (um OU outro),  e apenas embaralhando aleatoriamente os números dificilmente vais conseguir obter uma matriz quadrado mágico,  creio que seja necessário usar algum tipo de IA nesse código para formar as linhas e colunas com o mesmo valor.,  e seu código modificado está escrevendo os números certos que estão armazenados na Matriz:

#include    <stdlib.h>
#include    <stdio.h>
#include    <time.h>
#include    <string.h>
#include    <locale.h>
char* maiusc( char* );
void quadrado_magico
(
    int **matriz    , int  linhas                ,
    int   colunas   , int  valor_maximo          ,
    int  numeros[]  , int *somalinhas            ,
    int *somacolunas, int *somadiagonalPrincipal ,
    int *somadiagonalSecundaria
)
{
    int soma_numeros, soma_esperada;
    int eh_quadrado = 0; ///valor boleano = 1 pra true e 0 para false
    int tentativas = 0;
    while (eh_quadrado != 1 && tentativas < 5000)
    {
        ///Gerar uma lista de numeros de 0 ate n
        soma_numeros = 0;
        for (int i = 0; i < valor_maximo; i++)
        {
            numeros[i]    = i + 1      ;
            soma_numeros += numeros[i] ;
        }
        soma_esperada = soma_numeros / linhas;
        ///Embaralhar os numeros de forma aleatoria
        for (int i = valor_maximo - 1; i > 0; i--)
        {
            int j      = rand()% valor_maximo;
            int aux    = numeros[i];
            numeros[i] = numeros[j];
            numeros[j] = aux;
        }
        for (int i = 0; i < linhas; i++)
        {
            for (int j = 0; j < colunas; j++)
            {
                matriz[i][j] = numeros[i * linhas + j];
            }
        }
        ///inicializar com 0
        for (int i = 0; i < linhas; i++)
        {
            somalinhas [i] = 0;
            somacolunas[i] = 0;
        }
        ///soma linhas e colunas
        for  (int i = 0; i < linhas; i++)
        {
            for (int j = 0; j < colunas; j++)
            {
                somalinhas [i] += matriz[i][j];
                somacolunas[j] += matriz[i][j];
            }
        }
        *somadiagonalPrincipal  = 0;
        *somadiagonalSecundaria = 0;
        ///somas das diagonais
        for(int i = 0; i < linhas; i++)
        {
            *somadiagonalPrincipal  += matriz[i][i];
            *somadiagonalSecundaria += matriz[i][linhas - 1 - i];
        }
        ///assumimos que e um quadrado magico
        eh_quadrado = 1;
        for (int i = 0; i < linhas; i++)
        {
            for (int j = 0; j < colunas; j++)
            {
                if (somalinhas [i]          != soma_esperada ||
                    somacolunas[i]          != soma_esperada ||
                    *somadiagonalPrincipal  != soma_esperada ||
                    *somadiagonalSecundaria != soma_esperada  )
                {
                    eh_quadrado = 0;
                    break;
                }
            }
        }
        tentativas++;
    }
}
void impressao
(
    int **matriz, int linhas, int colunas, int numeros[],
    int *somalinhas, int *somacolunas,
    int *somadiagonalPrincipal, int *somadiagonalSecundaria
)
{
    char choice_soma[4], choice_array[4];
    printf("Você deseja ver a matriz resultante?(Sim/Não)\n");
    scanf ("%s", choice_array);
    maiusc(choice_array       ); /// converte p/ MaiUsculas
    if (strcmp(choice_array, "SIM") == 0 )
    {
        printf
        (
            "impressao:  %d linhaS  %d colunaS\n"
            "[                                \n"
            ,linhas , colunas
        );
        for(int f=0; f<linhas; f++)
        {
            for(int n=0; n<linhas; n++)
            {
                printf("%3d",matriz[f][n]);
            }
            if (f < linhas - 1)
            {
                puts("");
            }
        }
        printf("\n]\n");
    }
    printf("\nVocê deseja ver o resultado das somas ? ( Sim / Não )\n");
    scanf ("%s", choice_soma);
    maiusc( choice_soma     ); /// converte p/ MaiUsculas
    if (strcmp( choice_soma, "SIM") == 0 )
    {
        for (int i = 0; i < linhas; i++)
        {
            printf("A soma da %3dº Linha  é: %d\n", i+1, somalinhas[i]);
        }
        puts("");
        for (int j = 0; j < colunas; j++)
        {
            printf("A soma da %3dº Coluna é: %d\n", j+1, somacolunas[j]);
        }
        printf
        (
            "\n                       \n"
            "Diagonal Principal --: %d\n"
            "Diagonal Secundaria -: %d\n"
            ,     * somadiagonalPrincipal
            ,     *somadiagonalSecundaria
        );
    }
}
int main()
{
    setlocale(LC_ALL,"");
    srand(time(NULL)); /// Sempre gerar outro numero
    int tamanho = 0;
    printf
    (
        "Instruções:\n"
        "Um quadrado magico, é uma matriz de tamanhos iguais,"
        "(o mesmo numero\n"
        "de linhas e colunas) em que a soma de suas linhas, "
        "colunas e diagonais sejam iguais.\n"
        " Esse codigo vai gerar uma matriz de tamanho inserida "
        "pelo usuario, onde os numeros não\n"
        "não se repetem, e que seja um quadrado magico."
        "\nVamos lá...\n\n"
        "Insira o tamanho da matriz quadrada: "
    );
    scanf("%d", &tamanho);
    int valor_maximo = (tamanho * tamanho);
    int numeros[valor_maximo];
    int linhas = tamanho, colunas = tamanho;
    int **matriz = (int**) malloc(linhas * sizeof(int*));
    for (int i = 0; i < linhas; i++)
    {
        matriz[i] = (int *) malloc(colunas * sizeof(int) );
    }
    int *somal  =  (int*) malloc  (tamanho * sizeof(int) );
    int *somac  =  (int*) malloc  (tamanho * sizeof(int) );
    int *somaDP =  (int*) malloc  (tamanho * sizeof(int) );
    int *somaSC =  (int*) malloc  (tamanho * sizeof(int) );
    quadrado_magico( matriz,linhas, colunas,valor_maximo  ,
                    numeros, somal, somac, somaDP, somaSC);

    impressao      ( matriz, linhas,colunas,numeros, somal,
                     somac , somaDP, somaSC              );
    for (int i = 0; i < linhas; i++)
    {
        free(matriz[i]);
    }
    free(matriz);
    free(somal );
    free(somac );
    free(somaDP);
    free(somaSC);
    return     0;
}
char* maiusc( char* choice_array )
{
    int x = 0;
    do
    {
        if(choice_array[x] > 65 )choice_array[x] -= 32;
        x++;
    }
    while(choice_array[x] != 0 );
    return "";
}

 

Postado

O que eu quis dizer sobre os operadores && e ||, foi que quando é utilizado &&(and) o codigo faz a impressão de uma combinação de numeros que não retorna a condição estabelecida. Agora quando uutilizo o || ele parece entrar em "loop", já que nada é impresso, e o codigo não para de rodar.
Você poderia me dizer porque somente embaralhando os numeros, não seria possível achar uma matriz quadrado magico maior do que 3?  

  • Amei 1
Postado

@DaviFonsecx é possível sim ,  porém  quanto maior a matriz mais quantidade de números e combinações , e isso torna muito difícil formar as linhas e colunas com mesmo valor ,  pois está sendo feito aleatoriamente sem nenhuma organização , e a cada matriz criada e testada e não sendo válida ela é descartada e gerada outra e assim cada uma é apenas um chute, que pode dar certo ou não , e  para  criar tal matriz precisa calcular organizadamente com lógica modificando apenas alguns valores de forma a que todas linhas colunas tenha mesmo valor.   experimente colocar o valor "50000000" no "while" da função "quadrado_maqico", e coloque para ter 10 linhas, vai demorar 2,5 minutos para completar , e quanto maior for a matriz mais vai demorar .

Postado

Entendi, você tem alguma ideia de como organizar? Pensei em fixar um valor, e ir trocando as posições do restante. Ex.: 1(1 linha e 1 coluna) e embaralhar os outros numeros. Se não encontrar, fixar o 2 e embaralhar, tipo isso.
 

  • Curtir 1
Postado

@DaviFonsecx o melhor seria fazer "parecer" que é aleatório. Se você perguntar como assim parecer?

Um quadrado mágico depende de varias constantes, que acabam gerando muita entropia (se o quadrado é ímpar, par ou primo) e tornando quase impossível de gerar um aleatório.

Recomendo dar uma olhada nessa postagem Como criar um quadrado mágico de qualquer tamanho

 

Com um quadrado já feito é mais fácil modificar para parecer aleatório.

  • Curtir 2
Postado

@kgin  Por coincidência, eu acabei pesquisando sobre os métodos dos números pares, mas ainda não consegui implementar no código. O único que eu consegui implementar foi o método de siamese, que funciona para numeros impares. Mas estou tento bastante dificuldade com números pares.

  • Obrigado 1
Postado

Seu programa tem um bom número de problemas, e talvez seja melhorar reconsiderar o programa como um todo.

 

  • Lembro que falta um #include para stdio e é chato pra quem for testar seu programa ficar preenchendo coisas assim simples ANTES de poder estar o programa na tentativa de te ajudar
  • como está testando ainda, usar srand(time(0)) é mais problema do que solução: use uma constante. É melhor para você.
  • seu programa não é portável nem é padrão. O uso de VLA é algo de pouco sentido em geral, e existe mais em programas de estudantes. Nunca vi isso em uma biblioteca comum nem em um programa em produção. Por exemplo dos últimas coisas que usei nunca vi isso em stdlib, ou em SQLite, o banco de dados mais usado no planeto, ou em Asterisk, o padrão mundial de PABX VOIP, no kernel do linux, em alguma API do Windows, nada.  Falo de linhas como essas:
    printf("Insira o tamanho da matriz quadrada: ");
    scanf("%d", &tamanho);
    int valor_maximo = (tamanho * tamanho);
    int numeros[valor_maximo];

 

Faça um favor pra você e TESTE SEMPRE o retorno de scanf. Há uma boa razão para scanf retornar um int. Se o cara bater a mão num E ao tentar digitar 4 seu programa já era, a toa. 

  • É muito chato ficar esperando um prompt para então o programa rodar. Quando o cara vai rodar isso, e pode ser você --- principalmente agora que o programa nem funciona --- ele já sabe que quer gerar um quadrado mágico de uma certa ordem. Faça o simples e leia isso na linha de comando. Todo sistema gera isso, todo programa C recebe isso --- ok, programas em qualquer linguagem -- e deve ter uma boa razão para tal.

De volta ao código:

 

O programa sequer é interativo depois de receber o tamanho da matriz --- isso é chamado ordem --- então não parece ter muita razão para passar nada menos que 8 parâmetros (4 ponteiros) e alocar 4 áreas toda vez que roda o programa. O próprio valor da soma do quadrado mágico não é importante, é mais uma consequência do que um resultado.

 

Algoritmo x Sorteio:

 

Você pode sim tentar isso por sorteio sem um algoritmo, apenas definindo um limite para os valores e preenchendo a matriz. E ir testando até dar certo. Claro que para todas as combinações de N números em uma matriz de ordem M vai dar certo rapidinho, mas ao aumentar a ordem pode levar um bom tempo, uma eternidade. E o problema proposto nem é esse. E sugiro limitar bem o intervalo desses números.

 

O quadrado Mágico

 

Esse trem fascina pessoas e pessoas há muitos séculos e há muitos algoritmos para escrever um desses. Sugiro pesquisar e implementar um. É muito mais simples e é seu objetivo afinal. Se achar preciso eu posso descrever um aqui.

 

O Programa C

 

É muito mais simples usar funções objetivas, tipo uma API, com uma função que gera a matriz e uma outra que confere e opcionalmente imprime.

 

E usar um único parâmetro: a ordem. E uma estrutura para descrever a matiz, muito mais simples. Não use void. É problemático. Retorne por exemplo a matriz:

 

Se usa uma coisa tipo QM para descrever o tal quadrado mágico, pode planejar antes

 

QM* cria_QM(int ordem);
QM* destroi_QM( QM* matriz);
int mostra_QM(QM* matriz, cons char* titulo);
int testa_QM(QM* matriz);

 

É muito mais simples.

 

E comece com constantes, tipo o clássico

 

 8  3  4
 1  5  9
 6  7  2

 

para testar as funções de conferência e impressão. 

 

  • Obrigado 2
Postado
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdbool.h>

void gerar_num (int tamanho, int lista[]){
    
    for (int i = 0; i < (tamanho * tamanho); i++){
        lista[i] = i + 1;
    }
}

void tamanho_impar (int **matriz, int tamanho, int lista[]){ //algoritmo de siamese
    int num = 1;
    int linha = 0, coluna = tamanho / 2;
    
    for (int i = 0; i < tamanho; i++){
        for (int j = 0; j < tamanho; j++){
           matriz[i][j] = 0;
        }
    }

    while (num <= tamanho * tamanho){
        matriz[linha][coluna] = lista[num-1];
        num++;
        linha--;
        coluna++;
        if (num % tamanho == 1)
        {
            linha += 2;
            --coluna;
        }
        else{
            if (coluna == tamanho) coluna -= tamanho;
            else if (linha < 0) linha += tamanho;
        }
    }
}

void tamanho_quadrado (int **matriz, int **matriz_inversa, int tamanho, int lista[]){// duplo quadrado
    int num = 1;

    for (int i = 0; i < (tamanho * tamanho); i++){
        lista[i] = i + 1;
    }
    
    if (tamanho %4 == 0){
        
        for (int i = 0; i < tamanho; i++){
            for (int j = 0; j < tamanho; j++){
                matriz[i][j] = lista[i * tamanho + j];
                matriz_inversa[i][j] = lista[tamanho * tamanho - num];
                num++;
            }
        }
        for (int g = 0; g < tamanho; g += 4){
            for (int h = 0; h < tamanho; h += 4){
                for (int i = 0; i < 4; i++){
                    for (int j = 0; j < 4; j++){
                        if (i == j || (i+j) == 3){
                        matriz[g+i][h+j] = 0;
                        }
                        if (!(i == j || (i + j) == 3)) {
                            matriz_inversa[g + i][h + j] = 0;
                        }
                    }
                }
            }
        }
        for (int g = 0; g < tamanho; g += 4){        
            for(int h = 0; h < tamanho; h += 4){    
                for (int i = 0; i < 4; i++){
                    for (int j = 0; j < 4; j++){
                        if (matriz_inversa[g+i][h+j] != 0){
                            matriz[g+i][h+j] = matriz_inversa[g+i][h+j];
                        }
                    }
                }
            }
        }
    }
}
void tamanho_naoquadrado (int **matriz, int tamanho, int lista[]){//metodo LUX
    for (int i = 0; i < tamanho; i++){
            for (int j = 0; j < tamanho; j++){
               matriz[i][j] = 0;
            }
        }
    
    int num = 1;
    int central = tamanho / 2;
    
    for (int i = 0; i < central; i++){
        for (int j = 0; j < central; j++){
            matriz[i][j] = num;
            matriz[i+central][j+central] = num + central * central;
            matriz[i][j + central] = num + 2 * central * central;
            matriz[i + central][j] = num + 3 * central * central;
            num++;
        }
    }
    
    for (int i = 0; i < central; i++){
        for (int j = 0; j < tamanho / 4; j++){
            
            int aux = matriz[i][j];
            matriz[i][j] = matriz[i+central][j];
            matriz[i+central][j] = aux;
          
        }
    }
    
    for (int i = 0; i < central; i++){
        for (int j = tamanho - 1; j >= tamanho - tamanho / 4 +1; j--){
           int aux = matriz[i][j];
            matriz[i][j] = matriz[i+central][j];
            matriz[i+central][j] = aux;
        }
    }
    
    if (tamanho > 4){
        for (int i = 0; i < central / 2; i++) {
            int aux = matriz[i][central / 2];
            matriz[i][central / 2] = matriz[i + central][central / 2];
            matriz[i + central][central / 2] = aux;
        }
    }
    
}
void somaLinhasColunas (int **matriz, int tamanho, int *somaLinhas, int *somaColunas){
    
    for (int i = 0; i < tamanho; i++){
            somaLinhas[i] = 0;
            somaColunas[i] = 0;
    }
    
    for (int i = 0; i < tamanho; i++){
        for (int j = 0; j < tamanho; j++){
            somaLinhas[i] += matriz[i][j];
            somaColunas[j] += matriz[i][j];
        }
    }
}
void somaDiagonais(int **matriz, int tamanho, int *DiagonalPrincipal, int *DiagonalSecundaria){
    
    *DiagonalPrincipal = 0;
    *DiagonalSecundaria = 0;
    
    for (int i = 0; i < tamanho; i++){
        *DiagonalPrincipal += matriz[i][i];
        *DiagonalSecundaria += matriz[i][tamanho - 1 - i];
    }
}


bool quadrado_magico(int tamanho, int *somaLinhas, int *somaColunas, int DiagonalPrincipal, int DiagonalSecundaria){
    int soma_esperada = tamanho * (tamanho * tamanho + 1)/2;
    bool eh_quadrado = true;
    
    
    
    for (int i = 0; i < tamanho; i++){
        if (somaLinhas[i] != soma_esperada || somaColunas[i] != soma_esperada){
            eh_quadrado = false;
            break;
        }
    }
    
    if(DiagonalPrincipal != soma_esperada || DiagonalSecundaria != soma_esperada){
        eh_quadrado = false;
    }
    
    
    return eh_quadrado;
}

void imprimir(int **matriz, int tamanho, int *somaLinhas, int *somaColunas, int DiagonalPrincipal, int DiagonalSecundaria){
    
    char escolha[4];
 
        for (int i = 0; i < tamanho; i++){
            for (int j = 0; j < tamanho; j++){
                printf("%3d ", matriz[i][j]);
            }
            printf("\n");
        }
        
        printf("\n");
        
        for (int i = 0; i < tamanho; i++) {
            printf("Soma da %dª Linhas: %d \n",i+1, somaLinhas[i]);
        }
        printf("\n");
        for (int i = 0; i < tamanho; i++) {
            printf("Soma da %dª Coluna: %d\n",i+1, somaColunas[i]);
        }
        printf("\nSoma da Diagonal Principal: %d\n", DiagonalPrincipal);
        printf("Soma da Diagonal Secundária: %d\n", DiagonalSecundaria); 
    
    
    
}
int main()
{
    srand(time(0));
    
    int tamanho = 8;
    
    
    int linhas = tamanho, colunas = tamanho;
    int *somaColunas, *somaLinhas;
    int DiagonalPrincipal, DiagonalSecundaria;
    int lista[tamanho * tamanho];
    bool verificar;
    char escolha[4];
    
    //alocação de memória para matriz
    int **matriz = (int**) malloc (linhas * sizeof(int *));
    for (int i = 0; i < linhas; i ++){
        matriz[i] = (int*) malloc (colunas * sizeof (int));
    }
    
    int **matriz_inversa = (int**) malloc (linhas * sizeof(int *));
    for(int i = 0; i < linhas; i++){
        matriz_inversa[i] = (int*) malloc (colunas * sizeof(int));
    }
    //Demais alocações de memória
    
    somaLinhas = (int* ) malloc (tamanho * sizeof (int));
    somaColunas = (int* ) malloc (tamanho * sizeof (int));
    
    
        //Função para gerar
        gerar_num(tamanho, lista);
        
        //Funções para preencher a matriz de acordo com seu tipo
        if (tamanho %2 != 0) tamanho_impar(matriz, tamanho, lista);
        
        else if (tamanho % 4 == 0) tamanho_quadrado(matriz, matriz_inversa, tamanho, lista);
        
        else{
            tamanho_naoquadrado(matriz, tamanho, lista);
        }
        
        //Funções de soma
        somaLinhasColunas(matriz, tamanho, somaLinhas, somaColunas);
        somaDiagonais (matriz, tamanho, &DiagonalPrincipal, &DiagonalSecundaria);
        
        //verificar quadrado quadrado_magico
        verificar = quadrado_magico(tamanho, somaLinhas, somaColunas, DiagonalPrincipal, DiagonalSecundaria);
    
    //Funçao pra impressao
    if (verificar) imprimir(matriz, tamanho, somaLinhas, somaColunas, DiagonalPrincipal, DiagonalSecundaria);
    else printf("Não foi possível gerar um quadrado_magico.");
    
    
    //liberar as memórias alocadas
    for (int i = 0; i < linhas; i++){
        free(matriz[i]);
    }
    free(matriz);
     for (int i = 0; i < linhas; i++){
        free(matriz_inversa[i]);
    }
    free(matriz_inversa);
    free(somaLinhas);
    free(somaColunas);
    
    return 0;
}

@arfneto Sobre o #include, foi uma falta de atenção ao copiar o código pra cá, desculpe.
Poderia me explicar por que usar srand se torna um problema?
Acontece que eu sou "iniciante", finalizei meu primeiro periodo em SI, por agora. Esse programa é uma atividade opcional que foi passada, e eu quis tentar fazer.
Você fala sobre usar diretamente a constante no código? Sem pedir ao usuario para inserir algo?

Achei que void fosse mais ''simples'' por não retornar algo diretamente, e sim só realizar o procedimento.
Acabei dando uma pesquisada sobre quadrados mágicos, e refiz o codigo acima, um pouco diferente. No final ainda tenho problemas com ordens pares.
Optei por usar o Método Siameses para numeros impares, e o metodo do quadrado duplo para numeros multiplos de 4. Porém ordem par que não é multipla de 4, não consegui chegar em um resultado.
Você disse sobre usar um parametro só, no caso eu faria todas as interações direto em uma função só?

Vou deixar o codigo mais recente aqui, (provavelmente ainda contem erros) se você tiver um tempo e puder ir orientando sobre como melhorar...
 

  • Curtir 1
Postado
39 minutos atrás, DaviFonsecx disse:

Poderia me explicar por que usar srand se torna um problema?
Acontece que eu sou "iniciante", finalizei meu primeiro periodo em SI, por agora. Esse programa é uma atividade opcional que foi passada, e eu quis tentar fazer.

 

O "problema" do srand é simples: quando se está testando um algoritmo, em especial coisas que envolvem séries e matemática, você não quer nada aleatório. Você quer algo que possa reproduzir. Programas quando a gente está experimentando ou testando dão muita m. e você quer testar sempre com a mesma série até ficar seguro. 

 

Se rodar a p. do programa de novo e rand() retornar números completamente diferentes é mais problema que solução. Eu sugiro muito usar algo como AAMMDDHHMM, tipo srand(2410201112) porque é o seguro pra testar. Gera sempre as mesmas mãos no poker, sempre os mesmos dados, sempre a mesma matriz. É isso o que quer, porque programas em teste muitas vezes cancelam 30x na nossa cara.

 

44 minutos atrás, DaviFonsecx disse:

Você fala sobre usar diretamente a constante no código? Sem pedir ao usuario para inserir algo?

 

Claro. Não é esperto pedir pro usuário digitar algo inicialmente. Muito menos se o usuário vai ser você mesmo.

 

45 minutos atrás, DaviFonsecx disse:

Achei que void fosse mais ''simples'' por não retornar algo diretamente, e sim só realizar o procedimento.

 

Mas não é. Notou o exemplo que te mostrei? Retorne um objeto, a matriz completa. Ou um status. void é simplesmente nada. Um desperdício. Muitas vezes um erro mesmo.

 

46 minutos atrás, DaviFonsecx disse:

sobre quadrados mágicos, e refiz o codigo acima, um pouco diferente. No final ainda tenho problemas com ordens pares.
Optei por usar o Método Siameses para numeros impares, e o metodo do quadrado duplo para numeros multiplos de 4. Porém ordem par que não é multipla de 4, não consegui chegar em um resultado.

 

Está complicando as coisas para você mesmo. Use o clássico, com os números de 1 a n*n... Dois algoritmos se não funcionava nem para um? Não faça isso.

 

47 minutos atrás, DaviFonsecx disse:

Você disse sobre usar um parametro só, no caso eu faria todas as interações direto em uma função só?

 

?

 

Leu essa parte

 

2 horas atrás, arfneto disse:

Se usa uma coisa tipo QM para descrever o tal quadrado mágico, pode planejar antes

 

QM* cria_QM(int ordem);
QM* destroi_QM( QM* matriz);
int mostra_QM(QM* matriz, cons char* titulo);
int testa_QM(QM* matriz);

 

É muito mais simples.

 

Do que eu escrevi?

 

Sobre o novo programa

 

Não mudou praticamente nada do que eu expliquei... Claro que pode continuar desse modo que está escrevendo, mas considere que eu possa ter razão...

23 horas atrás, devair1010 disse:

pois está sendo feito aleatoriamente sem nenhuma organização , e a cada matriz criada e testada e não sendo válida ela é descartada e gerada outra e assim cada uma é apenas um chute, que pode dar certo ou não , e  para  criar tal matriz precisa calcular organizadamente com lógica modificando apenas alguns valores de forma a que todas linhas colunas tenha mesmo valor.

 

O nome disso é permutação. Acho que se estuda isso no final do ensino fundamental e depois no início do ensino médio. Você pega um universo de números e vai testando as possíveis permutações.

 

Isso ao invés de usar algum algoritmo. É muito mais simples de programar, mas pode sim levar uma eternidade e não é assim muito responsável politicamente 😄  pelo desperdício de recursos, já que um algoritmo te levaria a uma solução determinada em fração de segundo.

 

 

 

  • Obrigado 1
Postado
31 minutos atrás, arfneto disse:

Está complicando as coisas para você mesmo. Use o clássico, com os números de 1 a n*n... Dois algoritmos se não funcionava nem para um? Não faça isso

Como eu usaria os números de 1 a n*n? Poderia gerar uma lista de numeros de 1 a n², e organizar sistematicamente para que retorne uma matriz magica, seria isso?

 

33 minutos atrás, arfneto disse:

Leu essa parte

Li sim, mas fiquei meio perdido, faria um struct? E em seguida uma função?

 

34 minutos atrás, arfneto disse:

Isso ao invés de usar algum algoritmo. É muito mais simples de programar, mas pode sim levar uma eternidade e não é assim muito responsável politicamente 😄  pelo desperdício de recursos, já que um algoritmo te levaria a uma solução determinada em fração de segundo.

Consegui entender que não é viavel usar tentativa e erro, mas uma ordem tem mais de uma combinação possível pra a soma ser magica, certo? Mesmo que eu organize os numeros de maneira sistematica, talvez vai me retornar sempre a mesma matriz. Pensei que poderia fazer algo mais dinamico.

  • Curtir 1
  • Obrigado 1
Postado
15 minutos atrás, DaviFonsecx disse:

Li sim, mas fiquei meio perdido, faria um struct? E em seguida uma função?

 

Como assim?  não notou que tem 4 funções na lista e que elas são basicamente o seu problema?

 

16 minutos atrás, DaviFonsecx disse:

Consegui entender que não é viavel usar tentativa e erro

 

? Não foi pelo que eu disse. Eu disse que é bem viável e mais simples de programar. Só que pode demorar muito.

 

17 minutos atrás, DaviFonsecx disse:

talvez vai me retornar sempre a mesma matriz. Pensei que poderia fazer algo mais dinamico.

 

Não há problema em retornar sempre a mesma matriz. E de todo modo em geral se considera usar apenas os números de 1 a n onde n é a ordem da matriz... Seu problema é retornar um quadrado mágico de uma certa ordem, até onde escreveu.

 

Considere que a soma é sempre a mesma. Então uma matriz de ordem n vai ter n linhas com uma certa soma. Se usar os números de 1 a n vai ter a soma conhecida desde o ensino fundamental, certo? E aí divide por n e tem a tal constante mágica. É o simples. E vale como se sabe a metade da soma do primeiro com o último termo, multiplicada pelo número de termos. EXEMPLO mais simples para 3x3: então vai usar de 1 a 3x3, de 1 a 9 e vai ser (1+9)*9/2 = 45. Se a soma é 45 e são 3 linhas com a mesma soma então cada linha soma 15. E cada coluna. E as diagonais... Simples assim. Nada de C. Ensino fundamental apenas.

 

E vai usar isso para conferir a matriz. Se não usar um algoritmo apenas vai gerar as permutações e ver as que satisfazem às propriedades...

  • Curtir 2

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...