마방진

우선 마방진에 대한 개념은 가로,세로,대각선의 합이 같아지도록 정사각형 모양으로 배열한 행렬이다.

마방진 만드는 규칙

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);
}

실제 위 코드를 동작시키면 이와 같이 출력된다.