C-¾ð¾î·Î ÀÛ¼ºÇÑ
¸¶¹æÁø ÀÛ¼º ¼Ò½º ÇÁ·Î±×·¥


/***************************************************************************/
/*                       < <<     ¸¶  ¹æ  Áø     >> >                      */
/*                                                  - ÀÛ¼ºÀÚ:  ½Å ±Ç ¿µ    */
/***************************************************************************/

#define SIZE 160     /* ¹è¿­ÀÇSIZE¸¦ Áõ°¡½ÃŰ·Á¸é ¸Þ¸ð¸® °ü°è¸¦ °í·ÁÇϼ¼¿ä.*/

#include "stdio.h"
#include "stdlib.h"
#include "conio.h"

int m[SIZE][SIZE];

void odd_num(int n);
void even_num(int n);
void output(int n);
void _swap(int i1, int j1, int i2, int j2);

main()
{
    int i,j,n;
    char *s="           ";

    printf("\n***************************************************************************");
    printf("\n*                      <  < <    ¸¶  ¹æ  Áø    > >  >                     *");
    printf("\n*                 by;  ½Å  ±Ç  ¿µ(brainstm@chollian.net)                  *");
    printf("\n***************************************************************************");

    while(1) {
        printf("\n\n\n:-) Input the number(3-%d): ",SIZE);
        gets(s);
        n=atoi(s);
            if(n < 3 || n > SIZE) break;
        if(n%2) odd_num(n);
        else even_num(n);
        output(n);
    }

    printf("\n\n* .. Quit .. .  [[ <   MAGIC  SQUARE   > ]]  . .. *\n\n\n");
}

void odd_num(int n)
{
    int i,j,num=1;
    int nn=n*3/2;

    for(i=0; i < n; i++)
        for(j=0; j < n; j++)
            m[(j-i+nn)%n][(i*2-j+n)%n]=num++;
}

void even_num(int n)
{
    int i,j,num=1;
    int nminus=n-1,nmiddle=n/2,nn=n*n+1;
    int osl=0;
    int switch_row[2];
    int last_switch_column;
    int first_block=(n-2)/4,second_block=nminus-first_block;
    int first_inside=n/4,second_inside=nminus-first_inside;

    for(j=0; j < n; j++)
        for(i=0; i < n; i++) {
            if(i >= first_inside && i <= second_inside && j >= first_inside && j <= second_inside)
                m[i][j]=num;
            else if((i > first_block && i < second_block) || (j > first_block && j < second_block))
                m[i][j]=nn-num;
            else m[i][j]=num;
            num++;
        }
    if(!(n%4)) return;

    switch_row[0]=random(nmiddle-1)+first_block+1;
    switch_row[1]=random(nmiddle-1);
    if(switch_row[1] >= first_block) switch_row[1]+=(nmiddle+1);
    last_switch_column=random(nmiddle-1);
    if(last_switch_column >= first_block) last_switch_column+=(nmiddle+1);

/* À§ 5ÁÙÀÇ ÄÚµùÀº ³­¼ö ó¸® ¾øÀÌ ´Ü¼øÈ÷ ¾Æ·¡Ã³·³ ÇØµµ µË´Ï´Ù. 
    switch_row[0]=nmiddle;
    switch_row[1]=0;
    last_switch_column=0;
*/

    for(i=0; i < nmiddle; i++) {
        if(i==first_block || i==second_block) {
            osl=1-osl;
            continue;
        }
        _swap(second_block, i, second_block, nminus-i);
        _swap(i, first_block, nminus-i, first_block);
        _swap(i, second_block, nminus-i, second_block);
        _swap(i, switch_row[osl], nminus-i, switch_row[osl]);
    }
    for(i=first_block+1; i < second_block; i++) {
        _swap(first_block, i, second_block, i);
        _swap(i, first_block, i, second_block);
    }
    _swap(first_block, nmiddle, second_block, nmiddle);
    _swap(last_switch_column, first_block, last_switch_column, second_block);
}

void output(int n)
{
    int i,j,ch,err=0;
    unsigned long sum,sl,sc,sd1=0,sd2=0;

    sum=(unsigned long)n*(n*n+1)/2;
    printf(";-) SUM = %lu.     * ..check sum... .  .    ",sum);
    for(j=0; j < n; j++) {
        sd1+=m[j][j];
        sd2+=m[j][n-j-1];
        sl=0;
        sc=0;
        for(i=0; i < n; i++) {
            sl+=m[i][j];
            sc+=m[j][i];
        }
        if(sl!=sum) {
            err++;
            printf("\n> Sum of the row-(%d) is %lu. It's incorrect..",j+1,sl);
        }
        if(sc!=sum) {
            err++;
            printf("\n> Sum of the column-(%d) is %lu. It's incorrect..",j+1,sc);
        }
    }
    if(sd1!=sum) {
        err++;
        printf("\n> Sum of the diagonal-(\\) is %lu. It's incorrect..",j+1,sd1);
    }
    if(sd2!=sum) {
        err++;
        printf("\n> Sum of the diagonal-(/) is %lu. It's incorrect..",j+1,sd2);
    }
    if(err) printf("\n\n* %d errors are happened.",err);
    else printf("- O.K. -");
    printf("\n\n:-? Do you want to display(Y/n)? ");
    ch=getch();
    if(ch=='n' || ch=='N') return;
    printf("\n---+---------------------------------------------------------------------------");
    for(j=0; j < n; j++) {
        printf("\n%2d)] ",j+1);
        for(i=0; i < n; i++)
            printf("%4d,",m[i][j]);
    }
    printf("\n---+---------------------------------------------------------------------------");
}

void _swap(int i1, int j1, int i2, int j2)
{
    int k;

    k=m[i1][j1];
    m[i1][j1]=m[i2][j2];
    m[i2][j2]=k;
}