#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#define N 100
#pragma warning( disable : 4996 )
void OddMagicSquare(int nMagicSqr[][N], int nN, int nOrgRow, int nOrgCol, int nBgn);
void SnglyEvenMagicSquare(int nMagicSqr[][N], int nN);
int main()
{
void makeMagicSquare(int nMagicSqr[][N], int nN);
void showMagicSquare(int nMagicSqr[][N], int nN);
void checkMagicSquare(int nMagicSqr[][N], int nN);
int nN;
int nMagicSqr[N][N];
while (1)
{
printf("? ");
scanf("%d", &nN);
if (nN <= 2 || nN > N)
break;
makeMagicSquare(nMagicSqr, nN);
showMagicSquare(nMagicSqr, nN);
checkMagicSquare(nMagicSqr, nN);
putchar('\n');
}
printf("Bye, ....\n");
}
void makeMagicSquare(int nMagicSqr[][N], int nN)
{
int nRow, nCol;
for (nRow = 0; nRow < nN; nRow++)
{
for (nCol = 0; nCol < nN; nCol++)
{
nMagicSqr[nRow][nCol] = 0;
}
}
if(nN%2==1)
{
OddMagicSquare(nMagicSqr,nN,0,0,0);
}
else if(nN%2==0)
{
SnglyEvenMagicSquare(nMagicSqr,nN);
}
{
// else if (nN % 4 == 0)
//
// {
// DblyEvenMagicSquare(nMagicSqr[][N], nN);
// }
//
// else if (nN % 2 == 0)
//
// {
// SnglyEvenMagicSquare(nMagicSqr[][N], nN);
// }
// 마방진 초기화
// 홀수인 경우
// 이중 짝수인 경우
// 단일 짝수인 경우
}
}
static char sFmt1[] = "행 %1d";
static char sFmt2[] = "열 %1d";
static char sFmt3[] = "대 %1c";
static char sFmt4[] = "%1d ";
void InitMagicSquare(int nMagicSqr[][N], int nN)
{
for (int nRow = 0; nRow < nN; nRow++)
for (int nCol = 0; nCol < nN; nCol++)
nMagicSqr[nRow][nCol] = 0;
sFmt1[4] = sFmt2[4] = sFmt3[4] = (int)log10(nN - 1) + 0x31;
sFmt4[1] = (int)log10(nN * nN) + 0x31;
}
void OddMagicSquare(int nMagicSqr[][N], int nN, int nOrgRow, int nOrgCol, int nBgn)
{
int nRow=nOrgRow;
int nCol=(nOrgCol+nN) / 2;
while(++nBgn <= nN*nN)
{
nMagicSqr[nRow][nCol] = nBgn;
int nPrnRow = nRow, nPrvCol = nCol;
if (nMagicSqr[nRow][nCol])
{
nRow = nPrnRow + 1;
if(nRow<)
nCol = nPrvCol;
}
else
{
}
}
// 실습: (nRow, nCol)이 (0, 0)에서 1부터 시작,
// 과제: (nOrgRow, nOrgCol)에서 nBgn + 1부터 시작되도록 수정해야 한다
// 예제: 크기가 10인 경우, 4등분하면 크기가 5인 홀수 마방진이 생긴다.
// 17 24 1 8 15 67 74 51 58 65
// 23 5 7 14 16 73 55 57 64 66
// 4 6 13 20 22 54 56 63 70 72
// 10 12 19 21 3 60 62 69 71 53
// 11 18 25 2 9 61 68 75 52 59
// 92 99 76 83 90 42 49 26 33 40
// 98 80 82 89 91 48 30 32 39 41
// 79 81 88 95 97 29 31 38 45 47
// 85 87 94 96 78 35 37 44 46 28
// 86 93 100 77 84 36 43 50 27 34
// 홀수 마방진 A는 (0, 0)에서 시작하는 붉은색 블록에서 1부터 시작
// 홀수 마방진 B는 (5, 5)에서 시작하는 갈대색 블록에서 26부터 시작
// 홀수 마방진 C는 (0, 5)에서 시작하는 보라색 블록에서 51부터 시작
// 홀수 마방진 D는 (5, 0)에서 시작하는 하늘색 블록에서 76부터 시작
//
// 이렇게 다양한 홀수 마방진이 nOrgRow, nOrgCol, nBgn으로 매개변수로 호출될 수 있다
// 이러한 경우를 지원하도록 확장해야 한다.
}
void DblyEvenMagicSquare(int nMagicSqr[][N], int nN)
{
// 이번 과제의 주요 부분입니다.
// (i+j+1) 또는 (i-j)가 4의 배수 여부에 따라 ...
}
//
// 이 이후부터는 그냥 참고만 하기 바랍니다.
//
void SnglyEvenMagicSquare(int nMagicSqr[][N], int nN)
{
static int nOrg[][2] = { {0, 0}, {1, 1}, {0, 1}, {1, 0} };
int nH = nN / 2;
int nSqr = nH * nH;
for (int i = 0; i < 4; i++)
OddMagicSquare(nMagicSqr, nH, nOrg[i][0] * nH, nOrg[i][1] * nH, i * nSqr);
int nQ = nH / 2;
void SwitchHalf(int nMagicSqr[][N], int nCol, int nHalf);
for (int nCol = 0; nCol < nQ; nCol++)
SwitchHalf(nMagicSqr, nCol, nH);
for (int nCol = nH + nQ + 2; nCol < nN; nCol++)
SwitchHalf(nMagicSqr, nCol, nH);
void Swap(int& x, int& y);
Swap(nMagicSqr[nQ][0], nMagicSqr[nQ + nH][0]); // Left Center at 0-th SQR <--> Left Center at 2-th SQR
Swap(nMagicSqr[nQ][nQ], nMagicSqr[nQ + nH][nQ]); // Center cell at 0-th SQR <--> Center cell at 2-th SQR
}
void SwitchHalf(int nMagicSqr[][N], int nCol, int nHalf)
{
void Swap(int& x, int& y);
for (int nRow = 0; nRow < nHalf; nRow++)
Swap(nMagicSqr[nRow][nCol], nMagicSqr[nRow + nHalf][nCol]);
}
void Swap(int& x, int& y)
{
int t = x;
x = y;
y = t;
}
void showMagicSquare(int nMagicSqr[][N], int nN)
{
char FMTsqr[] = "%2d ";
FMTsqr[1] = (int)(log10)(nN * nN) + 0x31;
printf("\n[마방진]\n");
for (int nRow = 0; nRow < nN; nRow++)
{
for (int nCol = 0; nCol < nN; nCol++)
printf(FMTsqr, nMagicSqr[nRow][nCol]);
putchar('\n');
}
}
void checkMagicSquare(int nMagicSqr[N][N], int nN)
{
void checkMagicSquareRow(int nMagicSqr[N][N], int nN);
void checkMagicSquareCol(int nMagicSqr[N][N], int nN);
void checkMagicSquareDgl(int nMagicSqr[N][N], int nN, int nDir);
checkMagicSquareRow(nMagicSqr, nN);
checkMagicSquareCol(nMagicSqr, nN);
printf("\n[대각선 검사]\n");
checkMagicSquareDgl(nMagicSqr, nN, '\\');
checkMagicSquareDgl(nMagicSqr, nN, '/');
}
void checkMagicSquareRow(int nMagicSqr[N][N], int nN)
{
printf("\n[행 검사]\n");
for (int nRow = 0; nRow < nN; nRow++)
{
printf(sFmt1, nRow);
int nSum = 0;
for (int nCol = 0; nCol < nN; nCol++)
{
printf("%c ", nCol ? '+' : ':');
printf(sFmt4, nMagicSqr[nRow][nCol]);
nSum += nMagicSqr[nRow][nCol];
}
printf("= %d\n", nSum);
}
}
void checkMagicSquareCol(int nMagicSqr[N][N], int nN)
{
printf("\n[열 검사]\n");
for (int nCol = 0; nCol < nN; nCol++)
{
printf(sFmt2, nCol);
int nSum = 0;
for (int nRow = 0; nRow < nN; nRow++)
{
printf("%c ", nRow ? '+' : ':');
printf(sFmt4, nMagicSqr[nRow][nCol]);
nSum += nMagicSqr[nRow][nCol];
}
printf("= %d\n", nSum);
}
}
void checkMagicSquareDgl(int nMagicSqr[N][N], int nN, int nDir)
{
int nSum = 0, nDgnl = nDir == '/';
int nCol = nDgnl * (nN - 1), nDelta = 1 - nDgnl * 2;
printf(sFmt3, nDir);
for (int nRow = 0; nRow < nN; nRow++, nCol += nDelta)
{
printf("%c ", nRow ? '+' : ':');
printf(sFmt4, nMagicSqr[nRow][nCol]);
nSum += nMagicSqr[nRow][nCol];
}
printf("= %d\n", nSum);
}