You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现生命游戏问题:next_step函数返回结果异常

生命游戏代码问题排查

这个程序负责实现生命游戏的下一代状态计算,核心包含三个部分:计算每个细胞的存活邻居数量、应用生命游戏规则、处理1/0与True/False的类型转换。目前本地测试结果看似正确,但提交到教师评测网站后被判定结果错误,以下是原代码及问题分析:

原代码

from typing import List
import copy as cp
def next_step(pop: List[List[bool]]) -> List[List[bool]]:
    ''' renvoie la prochaine population '''
    L=[[0]*len(pop) for x in range(len(pop))] #init
    M=cp.deepcopy(pop)
    #coins
    L[0][0]=pop[0][1]+pop[1][1]+pop[1][0]+pop[0][-1]+pop[1][-1]+pop[-1][-1]+pop[-1][0]+pop[-1][1]
    L[0][-1]=pop[0][0]+pop[1][0]+pop[-1][0]+pop[0][-2]+pop[-1][-2]+pop[-1][-1]+pop[1][-1]+pop[1][-2]
    L[-1][0]=pop[0][0]+pop[0][1]+pop[-2][0]+pop[-2][-1]+pop[-1][1]+pop[-1][0]+pop[-1][-1]+pop[-2][-1]
    L[-1][-1]=pop[0][0]+pop[0][-2]+pop[0][-1]+pop[-2][0]+pop[-1][0]+pop[-2][-2]+pop[-2][-1]+pop[-1][-2]
    #bords
    for i in range(1,len(pop)-1):
        L[0][i]=pop[0][i-1]+pop[0][i+1]+pop[1][i]+pop[1][i-1]+pop[1][i+1]+pop[-1][i]+pop[-1][i-1]+pop[-1][i+1]
    for i in range(1,len(pop)-1):
        L[-1][i]=pop[-1][i-1]+pop[-1][i+1]+pop[-2][i]+pop[-2][i-1]+pop[-2][i+1]+pop[0][i]+pop[0][i-1]+pop[0][i+1]
    for j in range(1,len(pop)-1):
        L[j][0]=pop[j-1][0]+pop[j+1][0]+pop[j][1]+pop[j-1][1]+pop[j+1][1]+pop[j-1][-1]+pop[j][-1]+pop[j+1][-1]
    for j in range(1,len(pop)-1):
        L[j][-1]=pop[j-1][-1]+pop[j+1][-1]+pop[j][-2]+pop[j-1][-2]+pop[j+1][-2]+pop[j][0]+pop[j-1][0]+pop[j+1][0]

    #milieu
    for u in range(1,len(pop)-1):
        for v in range(1,len(pop)-1):
            L[u][v]=pop[u-1][v-1]+pop[u-1][v]+pop[u-1][v+1]+pop[u][v-1]+pop[u][v+1]+pop[u+1][v-1]+pop[u+1][v]+pop[u+1][v+1]

    for k in range(len(M)):
        for i in range(len(M)):
            if L[k][i]==3:
                if pop[k][i]==False:
                    M[k][i]=True
            elif L[k][i]==2:
                if pop[k][i]==True:
                    M[k][i]=True
            else:
                M[k][i]=False
    for k in range(len(M)):
        for i in range(len(M)):
            if M[k][i]==0:
                M[k][i]=False
            if M[k][i]==1:
                M[k][i]=True
    return M

核心问题分析

  1. 边界邻居计数错误:手动计算角落和边缘细胞的邻居时出现重复统计,比如L[-1][0]中重复累加了pop[-2][-1],导致邻居数量统计失真,这是评测不通过的主要原因。
  2. 生命游戏规则实现错误:当邻居数为3时,原代码仅处理原细胞为False的情况,但根据规则,无论原细胞是否存活,只要有3个邻居就会存活(或复活),这个判断逻辑遗漏了原细胞为True的场景。
  3. 冗余类型转换:最后循环将0/1转为True/False完全多余,因为M是从pop深拷贝而来的bool类型矩阵,前面的逻辑已经直接赋值True/False,这一步不仅无用,还可能引入潜在错误。
  4. 假设输入为方阵:代码默认输入是行列数相等的方阵,但函数参数允许任意二维bool列表,若评测用例包含非方阵输入,会直接报错。

修正后的代码

from typing import List
import copy as cp

def next_step(pop: List[List[bool]]) -> List[List[bool]]:
    ''' 返回下一代细胞状态 '''
    rows = len(pop)
    cols = len(pop[0]) if rows > 0 else 0
    # 初始化邻居计数矩阵
    neighbor_count = [[0] * cols for _ in range(rows)]
    new_pop = cp.deepcopy(pop)

    # 遍历每个细胞,计算8个方向的邻居数(循环边界处理)
    for i in range(rows):
        for j in range(cols):
            count = 0
            # 遍历所有相邻方向(排除自身)
            for di in (-1, 0, 1):
                for dj in (-1, 0, 1):
                    if di == 0 and dj == 0:
                        continue
                    # 模运算实现循环边界(边缘细胞的邻居对应对面边缘)
                    ni = (i + di) % rows
                    nj = (j + dj) % cols
                    count += pop[ni][nj]
            neighbor_count[i][j] = count

    # 应用生命游戏规则
    for i in range(rows):
        for j in range(cols):
            cnt = neighbor_count[i][j]
            if cnt == 3:
                new_pop[i][j] = True
            elif cnt != 2:
                new_pop[i][j] = False
            # 邻居数为2时保持原状态,无需修改

    return new_pop

修正说明

  • 用通用的8方向遍历+模运算处理循环边界,彻底避免手动计算边界时的重复/遗漏问题,代码更简洁易维护。
  • 修正规则逻辑:邻居数为3时直接设为True;邻居数不为2时设为False;邻居数为2时保持原状态(因new_pop是深拷贝,无需额外赋值)。
  • 移除冗余的类型转换步骤,保留bool类型的一致性。
  • 兼容非方阵输入,扩大代码适用范围。

内容的提问来源于stack exchange,提问作者THIBZ EDIT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 00:01:03