#include
#include
#include
void odd_order( int );
void doubly_even( int );
void half_even( int, int, int, int, int );
void j_loop( int, int, int, int, int, int, int );
void half_loop( int, int, int, int, int, int, int, int );
int main()
{
char num[10];
int n;
clrscr();
puts("Pon el numero de casillas que tendra de lado el cuadrado magico:");
gets(num);
n = atoi( num );
if (n < 1 || n == 2) {
printf( "Entrada invalida...\n" );
exit(1);
}
if ((n & 1))
odd_order(n);
else if (!(n & 2))
doubly_even(n);
else
{
half_even( n, 3, 1, 2, 0 );
half_even( n, 0, 2, 1, 3 );
}
printf( "\n\nLa suma de cada fila es %8d\n\n", n*(n*n+1) >> 1 );
getch();
return;
}
/********************/
/* "lozenge" method */
/********************/
void odd_order( int N )
{
int i, j, N1, N3, t;
N1 = (N-1)>>1;
N3 = N1-1;
for (i=1; i <= N; i++)
{
for (j=1; j <=N; j++)
{
t = N1-i+j;
if (t >= N) t -= N;
else if (t < 0) t += N;
printf( "%5d ", 1 + t + N * ((N3+i+j)%N) );
}
printf( "\n" );
}
}
/**********************/
/* "Nine block method */
/**********************/
void doubly_even( int n )
{
int i, j, num = 1;
int nminus = n-1, nn = n*n+1;
int block1 = (n-2)>>2, block2 = nminus - block1;
int inside1 = n>>2, inside2 = nminus - inside1;
for (j=0; j < n; j++)
{
for (i=0; i < n; i++)
{
if (i >= inside1 && i <= inside2 &&
j >= inside1 && j <= inside2)
printf( "%5d ", num );
else if ((i > block1 && i < block2) ||
(j > block1 && j < block2))
printf( "%5d ", nn - num );
else
printf( "%5d ", num );
num++;
}
printf( "\n" );
}
}
/******************************************/
/* quarter-board plus swap pattern method */
/******************************************/
/* print half a board
*/
void half_even( int n, int a1, int a2, int a3, int a4 )
{
int i, halfn = n>>1, m = n>>2;
for (i=1; i <= m; i++) /* upper m rows of half board */
j_loop( 0, i, n, a1, a2, a3, a4 );
j_loop( 1, m+1, n, a1, a2, a3, a4 ); /* middle row of half board */
for (i=m+2; i <= halfn; i++)
j_loop( 0, i, n, a1, a2, a3, a4 ); /* lower m rows of half board */
}
/* print i'th row of this half */
/*******************************/
void j_loop( int mid_row, int i, int n, int a1, int a2, int a3, int a4 )
{
half_loop( 1, mid_row, i, n, a1, a2, a3, a4 ); /* first half of row */
half_loop( 0, mid_row, i, n, a1, a2, a3, a4 ); /* second half of row */
printf( "\n" );
}
/* print half of i'th row */
/**************************/
void half_loop( first_half, mid_row, i, n, a1, a2, a3, a4 )
int first_half, mid_row, i, n, a1, a2, a3, a4;
{
int N = n>>1, m = n>>2;
int j, t, val, N1 = (N-1)>>1, N3 = (N-3)>>1;
int offset = (n*n)>>2; /* difference between quarter boards */
for (j=1; j <= N; j++)
{
t = N1-i+j;
if (t >= N) t -= N;
else if (t < 0) t += N;
val = 1 + t + N*((N3+i+j)%N); /* val is corresponding value
in upper-left quarter */
if (first_half)
{
if ((mid_row && j > 1 && j <= m+1) || (!mid_row && j <= m))
val += a1*offset; /* swap square with corr. square */
else /* in other half of board */
val += a4*offset; /* don't swap */
}
/* second half */
/***************/
else if (j > (N-m+1))
val += a2*offset; /* swap square */
else
val += a3*offset; /* don't swap */
printf( "%5d ", val );
}
}