/* Glenn C. Rhoads. Copyright July 28, 2000 */
#include
#include
void odd_order( int );
void doubly_even( int );
void half_even( int, int, int, int, int );
void row_i( int, int, int, int, int, int, int );
void half_row( int, int, int, int, int, int, int, int );
int main( int argc, char **argv )
{
int n = atoi( argv[1] );
if (n < 1 || n == 2) {
printf( "invalid input\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\nThe sum of each row and column is %8d\n\n", n*(n*n+1) >> 1 );
exit(0);
}
/********************/
/* "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 && /* middle block */
j >= inside1 && j <= inside2)
printf( "%5d ", num );
else if ((i > block1 && i < block2) || /* not middle block */
(j > block1 && j < block2)) /* and not corner block */
printf( "%5d ", nn - num );
else /* corner block */
printf( "%5d ", num );
num++;
}
printf( "\n" );
}
}
/******************************************/
/* quarter-board plus swap pattern method */
/******************************************/
/* print half a board
*/
void half_even( int n, int q1, int q2, int q3, int q4 )
{
int i, halfn = n>>1, m = n>>2;
for (i=1; i <= m; i++) /* upper m rows of half board */
row_i( 0, i, n, q1, q2, q3, q4 );
row_i( 1, m+1, n, q1, q2, q3, q4 ); /* middle row of half board */
for (i=m+2; i <= halfn; i++)
row_i( 0, i, n, q1, q2, q3, q4 ); /* lower m rows of half board */
}
/* print i'th row of this half */
/*******************************/
void row_i( int mid_row, int i, int n, int q1, int q2, int q3, int q4 )
{
half_row( 1, mid_row, i, n, q1, q2, q3, q4 ); /* first half of row */
half_row( 0, mid_row, i, n, q1, q2, q3, q4 ); /* second half of row */
printf( "\n" );
}
/* print half of i'th row */
/**************************/
void half_row( first_half, mid_row, i, n, q1, q2, q3, q4 )
int first_half, mid_row, i, n, q1, q2, q3, q4;
{
int N = n>>1, m = n>>2;
int j, t, val, N1 = (N-1)>>1, N3 = N1 - 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 += q1*offset; /* swap square with corr. square */
else /* in other half of board */
val += q4*offset; /* don't swap */
}
/* second half */
/***************/
else if (j > (N-m+1))
val += q2*offset; /* swap square */
else
val += q3*offset; /* don't swap */
printf( "%5d ", val );
}
}