# 2016秋 魔法陣 def shokika(N): """図4の shokika(N) 関数を再現""" # 配列を (N+2) x (N+2) で用意 (Pythonは0-indexedのため、1〜N+1を扱うために+1余裕を持たせる) # houjin[y][x] の形でアクセス houjin = [[0 for _ in range(N + 2)] for _ in range(N + 2)] # 定数の定義 (0〜N^2 以外の適当な値) SOTO_MIGI = -1 SOTO_SHITA = -2 SOTO_KADO = -3 # 太枠内の初期化 for y in range(1, N + 1): for x in range(1, N + 1): houjin[y][x] = 0 # [イ] houjin[y][N+1] に SOTO_MIGI を代入 houjin[y][N + 1] = SOTO_MIGI # [ウ] 下側の外枠の初期化 for x in range(1, N + 1): houjin[N + 1][x] = SOTO_SHITA # 右下角の初期化 houjin[N + 1][N + 1] = SOTO_KADO return houjin, SOTO_MIGI, SOTO_SHITA, SOTO_KADO def mahoujin(N): """図4の mahoujin(N) 関数を再現""" houjin, SOTO_MIGI, SOTO_SHITA, SOTO_KADO = shokika(N) # 初期位置の設定 y = N # 最下行 x = (N + 1) // 2 # [エ] 中央の列 suuji = 1 houjin[y][x] = suuji # [オ] suuji が N*N 未満の間繰り返す while suuji < N * N: # 現在位置を保存 yb = y xb = x # 右下へ移動 y = y + 1 x = x + 1 # (F) 部分:外枠にはみ出した時の処理 if houjin[y][x] == SOTO_SHITA: y = 1 elif houjin[y][x] == SOTO_MIGI: x = 1 elif houjin[y][x] == SOTO_KADO: y = 1 x = 1 # [カ][キ] 移動先にすでに数字がある場合の処理 if houjin[y][x] != 0: y = yb - 1 x = xb suuji += 1 houjin[y][x] = suuji return houjin def print_houjin(houjin, N): """結果を綺麗に表示する補助関数""" for y in range(1, N + 1): row = [str(houjin[y][x]).zfill(2) for x in range(1, N + 1)] print(" ".join(row)) # 実行例 (N=3) N = 3 result = mahoujin(N) print(f"{N}x{N} の魔方陣:") print_houjin(result, N)