それ,numpy で書かない?--6--
Python ではリストがよく使われる。また,for ループが遅いのでリストに特化したリスト内包表記も推奨されることが多い。
それなりの根拠があるからではあるが...
課題:リストではなく二次元配列を使う。
リストをうまく操ろうとしてリスト内包表記を濫用すると,とても見通しの悪い,醜いプログラムになる。
副次効果:他の部分のプログラムもシェープアップされる。
以下に,奇数魔方陣を作って,正しいかどうか検証するプログラムを二通り書いて比較してみる。
1. リストとリスト内包表記を使う
def generate_odd_magic_square(n):
magic_square = [[0] * n for _ in range(n)]
num = 1
i, j = 0, n // 2
while num <= n * n:
magic_square[i][j] = num
num += 1
new_i, new_j = (i - 1) % n, (j + 1) % n
if magic_square[new_i][new_j]:
i += 1
else:
i, j = new_i, new_j
return magic_square
def print_magic_square(magic_square):
for row in magic_square:
print(" ".join(map(str, row)))
def check_magic_square(square):
n = len(square)
magic_constant = n * (n**2 + 1) // 2
# 行の合計をチェック
for row in square:
if sum(row) != magic_constant:
return False
# 列の合計をチェック
for j in range(n):
col_sum = sum(square[i][j] for i in range(n))
if col_sum != magic_constant:
return False
# 対角線の合計をチェック
diagonal_sum1 = sum(square[i][i] for i in range(n))
diagonal_sum2 = sum(square[i][n - 1 - i] for i in range(n))
if diagonal_sum1 != magic_constant or diagonal_sum2 != magic_constant:
return False
return True
n = 7
magic_square = generate_odd_magic_square(n)
print_magic_square(magic_square)
check_magic_square(magic_square)
30 39 48 1 10 19 28
38 47 7 9 18 27 29
46 6 8 17 26 35 37
5 14 16 25 34 36 45
13 15 24 33 42 44 4
21 23 32 41 43 3 12
22 31 40 49 2 11 20
True
2. Nupmhy ndarray を使う
import numpy as np
def generate_odd_magic_square(n):
magic_square = np.zeros((n, n), dtype=int)
i, j = 0, n // 2
for num in range(1, n**2 + 1):
magic_square[i, j] = num
new_i, new_j = (i - 1) % n, (j + 1) % n
if magic_square[new_i, new_j]:
i += 1
else:
i, j = new_i, new_j
return magic_square
def check_magic_square(square):
n = square.shape[0]
magic_constant = n * (n**2 + 1) // 2
# 行の合計をチェック
if np.all(np.sum(square, axis=1) != magic_constant):
return False
# 列の合計をチェック
if np.all(np.sum(square, axis=0) != magic_constant):
return False
# 対角線の合計をチェック
return np.trace(square) == magic_constant and np.trace(np.fliplr(square)) == magic_constant
n = 9
test_square = generate_odd_magic_square(n)
print("生成された魔方陣:")
print(test_square)
if check_magic_square(test_square):
print("魔方陣は正しいです。")
else:
print("魔方陣は正しくありません。")
生成された魔方陣:
[[47 58 69 80 1 12 23 34 45]
[57 68 79 9 11 22 33 44 46]
[67 78 8 10 21 32 43 54 56]
[77 7 18 20 31 42 53 55 66]
[ 6 17 19 30 41 52 63 65 76]
[16 27 29 40 51 62 64 75 5]
[26 28 39 50 61 72 74 4 15]
[36 38 49 60 71 73 3 14 25]
[37 48 59 70 81 2 13 24 35]]
魔方陣は正しいです。