Quadrado Mágico

Publicado por Enzo de Brito Ferber (última atualização em 14/12/2012)

[ Hits: 5.339 ]

Homepage: http://www.maximasonorizacao.com.br

Download magicsquare.c




Comentei bastante o código e coloquei as regras de construção do quadrado no cabeçalho inicial.

Como ficou extenso, não vou postar na descrição. O código está disponível para visualização no browser.

  



Esconder código-fonte

/* 
 * Magic Square
 *
 * @Author: Enzo Ferber
 *        : enzoferber@gmail.com
 *
 * O QUADRADO MÁGICO
 * -----------------
 *
 * [*] As regras:
 * ~~~~~~~~~~~~~~
 *
 * 1. A matriz sempre terá os lados ímpares.
 * 
 * 2. O primeiro número é posicionada no meio da primeira coluna.
 * 
 * 3. O próximo número é colocado deslocando uma posição para cima
 *    e  uma posição para direita. Caso seja alcançada uma das bordas
 *    do quadrado, a posição é invertida.
 *
 * 4. Caso já haja um número na nova posição, volta-se a posição antiga
 *    e apenas descemos linha. A coluna continua a mesma.
 *
 * [*] Exemplo com cubo 3x3:
 * ~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * 0 1 0    Posição Inicial (Regra 1 e 2)
 * 0 0 0
 * 0 0 0
 *
 * 0 1 0    Posição 2 (Regra 3) 
 * 0 0 0               
 * 0 0 2
 *
 * 0 1 0    Posição 3 (Regra 3)
 * 3 0 0
 * 0 0 2              
 *
 * Seguindo a regra, a próxima posição seria o quadrado onde está o número
 * 1. Então, seguindo a regra 4, voltamos para a posição anterior (3), e 
 * descemos uma linha.
 *
 * 0 1 0    Posição 4 (Regra 4)
 * 3 0 0
 * 4 0 2
 *
 * [*] Compilação e Execução:
 * ~~~~~~~~~~~~~~~~~~~~~~~~ 
 *
 * $ gcc -o magicsquare magicsquare.c
 * $ ./magicsquare 3
 *    8    1    6 
 *    3    5    7 
 *    4    9    2 
 *
 *     [*] Magic Constant: 15
 * $
 *
 */

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

#define INIT_NUMBER      0x00

/*
 * Protótipos de funções
 */
int **buildsquare ( int );
void printsquare ( int ** , int );
void initsquare ( int **, int, int );
int calcfactor ( int **, int );

/*
 * Função para calcular a constante
 */
int calcfactor ( int **_square, int size )
{
   register int i, factor = 0;

   for ( i = 0; i < size; i++ ) factor += _square[0][i];

   return factor;
}

/* 
 * Função para inicializar o quadrado com
 * um dado número
 */
void initsquare ( int **_square, int size, int n )
{
   register int i, j;

   for ( i = 0; i < size; i++ )
      for ( j = 0; j < size; j++ )
         _square[i][j] = n;
}

/*
 * Construção do quadrado mágico
 */
int **buildsquare ( int size )
{
   int matrixsize = size * size;
   int **_square, row = 0, col = (size / 2), lastRow, lastCol;
   register int i;

   /*
    * Aloca linhas do quadrado
    */
   _square = (int **) malloc ( size * sizeof(int *));

   /*
    * Para cada linha, aloca colunas
    */
   for ( i = 0; i < size; i++ )
      *(_square + i) = (int *) malloc ( size * sizeof(int));

   /*
    * Checagem de memória
    */
   if ( !_square)
   {
      printf ( " [*] Error: Couldn't malloc() memory.\n");
      return NULL;
   }

   /*
    * Inicializa o quadrado com zeros
    */
   initsquare ( _square, size, INIT_NUMBER );

   /*
    * Coloca o primeiro número no quadrado
    *
    * 0 1 0
    * 0 0 0
    * 0 0 0
    */
   (_square[row][col]) = 1;

   for ( i = 2; i <= matrixsize; i++ )
   {
      /*
       * backup
       */
      lastRow = row;
      lastCol = col;

      /* 
       * Cálculo de coluna e linha
       */
      row = ( row == 0 ) ? size - 1 : row - 1;
      col = ( col == ( size - 1 )) ? 0 : col + 1;

      /* 
       * Se o número for zero, o quadrado está pronto para receber
       * dados novos...
       */
      if ( _square[row][col] == 0 )
         (_square[row][col]) = i;
      else
      {
         /*
          * Se não for zero, significa que um número já foi inserido
          * na posição, então a regra é voltar para a ultima posição e 
          * "descer" uma linha na matriz, mantendo a coluna.
          */
         row = lastRow + 1;
         col = lastCol;

         (_square[row][col]) = i;
      }
   }
   /*
    * Retorna o quadrado
    */
   return _square;
}

void printsquare ( int **_square, int size )
{
   register int i, j;

   for ( i = 0; i < size; i++ )
   {
      for ( j = 0; j < size; j++ )
      {
         if ( _square[i][j] < 10 ) printf ( " " );
         if ( _square[i][j] < 100 ) printf ( " " );
         if ( _square[i][j] < 1000 ) printf ( " " );

         printf ( "%d ", (_square[i][j]) );
      }
      printf ( "\n");
   }
}

int main ( int argc, char *argv[] )
{
   /* 
    * O quadrado
    */
   int **magicsquare, size;

   /*
    * Assegura que o usuário entre com um número
    */
   if ( argc < 2 )
   {
      printf ( " [*] Usage: %s <odd_number>\n", argv[0] );
      exit ( EXIT_FAILURE );
   }

   size = atoi(argv[1]);

   /*
    * Assegura que o número é ímpar
    */
   if ( !( size % 2 ))
   {
      printf ( " [*] Error: Number must be odd.\n" );
      exit ( EXIT_FAILURE );
   }

   /*
    * Construção do quadrado
    */

   magicsquare = buildsquare ( size );

   /*
    * Erro
    */
   if ( !magicsquare )
   {
      printf ( " [*] Error: Couldn't build square matrix.\n");

      free ( magicsquare );
      exit ( EXIT_FAILURE );
   }

   /*
    * Imprime o quadrado
    */
   printsquare ( magicsquare, size );

   /*
    * Imprime a constante
    */
   printf ( "\n [*] Magic Constant: %d\n", calcfactor(magicsquare, size));

   return EXIT_SUCCESS;
}

Scripts recomendados

A - Comando Break

Filas

Contagem de elementos de um array

Goldbach

Media de N numeros


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts