幻方(magic square)是由唯一的、连续自然数组成的数组,其中所有行、列和两个主对角线上的和都相等。
洛书幻方(Luo Shu square):每一行、每一列和两条主对角线之和都是15。 Kurushima算法是生成幻方最优雅的算法之一, Kurushima算法只适用于奇数阶幻方,即任意n×n幻方,其中n是奇数。
def generate_kurushima_magic_square(order):"""使用Kurushima算法生成一个奇数阶的幻方。参数:order (int): 幻方的阶数,必须为奇数。返回值:list: 幻方,order x order的二维列表。"""if order % 2 == 0:raise ValueError("order must be an odd number")# 初始化一个order x order的二维列表,全为0magic_square = [[0] * order for _ in range(order)]# 初始位置在第一行的中间current_row, current_col = 0, order // 2magic_square[current_row][current_col] = 1# 填充幻方for number in range(2, order * order + 1):# 计算下一个数字的位置next_row, next_col = (current_row - 1) % order, (current_col + 1) % orderif magic_square[next_row][next_col] == 0:# 如果目标位置未被占用,移动到该位置current_row, current_col = next_row, next_colelse:# 如果目标位置已被占用,向下移动一格current_row = (current_row + 1) % order# 在当前确定的位置放置下一个数字magic_square[current_row][current_col] = numberreturn magic_squaredef print_magic_square(square):"""打印幻方。参数:square (list): 幻方的二维列表。每个元素都是一个列表,表示幻方的一行。功能描述:- 该函数将二维列表 `square` 打印为一个幻方的形式。- 每个数字按行和列对齐输出,以便清晰显示幻方的结构。- 行和列的标签用于标识行号和列号,从0开始。实现细节:- 首先,生成一个列标签的列表 `labels`,用于显示列号。每个标签被格式化为 '[x]' 的形式,其中 x 是列号。- 使用 `format_row` 定义一个行格式化字符串,以确保每列的内容按6个字符的宽度右对齐。- 打印列标签行,首先输出一个空字符串以对齐,然后输出所有的列标签。- 对于幻方的每一行,先输出行标签,再按行打印行内容。行标签与对应的行内容一一对应。"""labels = ['['+str(x)+']' for x in range(len(square))]format_row = "{:>6}" * (len(labels) + 1)print(format_row.format("", *labels))for label, row in zip(labels, square):print(format_row.format(label, *row))def validate_magic_square(square):"""验证给定的二维列表是否是一个正确的幻方。参数:square (list): 幻方的二维列表。返回值:bool: 如果是合法的幻方,返回True;否则返回False。"""order = len(square)expected_sum = order * (order * order + 1) // 2# 检查每一行的和是否等于预期的魔力常数for row in square:if sum(row) != expected_sum:return False# 检查每一列的和是否等于预期的魔力常数for col in range(order):if sum(square[row][col] for row in range(order)) != expected_sum:return False# 检查主对角线的和是否等于预期的魔力常数if sum(square[i][i] for i in range(order)) != expected_sum:return False# 检查副对角线的和是否等于预期的魔力常数if sum(square[i][order - 1 - i] for i in range(order)) != expected_sum:return False# 检查是否包含从1到order^2的所有数字all_numbers = set(range(1, order * order + 1))square_numbers = {num for row in square for num in row}if all_numbers != square_numbers:return Falsereturn True# 示例使用
n = 5
magic_square = generate_kurushima_magic_square(n)
print_magic_square(magic_square)
is_valid = validate_magic_square(magic_square)
print(f"幻方验证结果: {is_valid}")
[0] [1] [2] [3] [4]
[0] 17 24 1 8 15
[1] 23 5 7 14 16
[2] 4 6 13 20 22
[3] 10 12 19 21 3
[4] 11 18 25 2 9
幻方验证结果: True