마방진
우선 마방진에 대한 개념은 가로,세로,대각선의 합이 같아지도록 정사각형 모양으로 배열한 행렬이다.
마방진 만드는 규칙
1) 첫번째 행의 중앙에 1을 배열한다.
2) 왼쪽 대각선으로 올라가면서 빈자리에 1씩 큰 수를 배열한다.
이때 행렬의 밖으로 벗어나면 그 방향의 반대편에서 계속한다.
3) 만약 이동해서 채워야하는 자리에 이미 숫자가 배열되어 있다면, 정해진 위치 바로 아래에 숫자를 배열한다.
5x5 마방진 예시
규칙을 프로그램으로 짜기
- 입력 : 0으로 초기화된 n * n의 2차원 배열
table[n][n]
- 출력 : n * n의 magic square
행을 움직이는 변수 i, 열을 움직이는 변수 j
1) Rule : 첫 번째 행의 중앙에 1을 놓는다.
int i = 0, int j = (n-1)/2 ,
table[i][j] = 1;
2) Rule : 왼쪽 대각선 방향으로 올라가면서 빈자리에 1씩 큰 수를 놓는다. 이때 행렬의 밖으로 벗어나면 그 방향의 반대편에서 계속한다.
3) Rule : 만약 이동하려는 자리에 숫자가 이미 채워져 있으면 지금 위치의 바로 아래에 숫자를 놓는다.
#define MAX_SIZE 15
//마방진의 최대 사이즈를 15로 설정
void make_msquare(int table[][MAX_SIZE], int n);
// 마방진 구현하는 함수
void display(int table[][MAX_SIZE], int n);
// 구현한 마방진을 print 해서 보여주는 함수
int main() {
int n, r, c, sum = 0;
int table[MAX_SIZE][MAX_SIZE];
printf("Enter a number: ");
scanf("%d", &n);
if ((n < 1) || n > MAX_SIZE) {
printf("Error! size is out of range \n");
exit(0);
}
for (r = 0; r < n; r++) {
for (c = 0; c < n; c++) {
table[r][c] = 0;
}
}
// 마방진의 배열을 전부 0으로 초기화시켜줌
make_msquare(table,n);
display(table, n);
}
void make_msquare(int table[][MAX_SIZE], int n) {
int digit = 0;
int row, r, c, col;
r = 0; c = (n - 1) / 2;
// 행의 첫번째줄, 열의 중간부터 마방진을 시작한다.
table[r][c] = 1;
for (digit = 2; digit <= n * n; digit++) {
row = r - 1;
col = c - 1;
// 왼쪽 대각선 위로 올라가면서 수를 채울거라,
행과 열을 하나씩 빼준다.
if (row < 0) {
row = n - 1;
}
// 행이 0보다 작으면 즉, 가장 위에 열에서 더이상 올라갈 데가 없으면 n-1번째 (가장 아래)에서 다시 시작한다
if (col < 0) {
col = n - 1;
}
// 열이 0보다 작으면 즉, 가장 왼쪽에서 더 왼쪽으로 갈 데가 없으면 n-1번째 (가장 오른쪽)에서 다시 시작한다
if (table[row][col]) r++;
else {
r = row;
c = col;
}
table[r][c] = digit;
// 반복되는 횟수에 따라서 그 해당 테이블의 배열에 값을 넣어준다.
}
}
void display(int table[][MAX_SIZE], int n) {
int r, c;
int sum = 0;
for (r = 0; r < n; r++) {
for (c = 0; c < n; c++)
printf("%5d", table[r][c]);
printf("\n");
}
for (c = 0; c < n; c++) {
sum += table[0][c];
}
// 한 열의 number을 카운팅해서 한 열/헹/대각선의 Sum을 구함
printf("Row/Col/Diagonal Sum = %d \n ", sum);
}
실제 위 코드를 동작시키면 이와 같이 출력된다.