Python 中细胞自动机代码的问题与解决方案

28 阅读2分钟

1.在 Python 中,有一个实现了基本细胞自动机的代码。这个代码在 Python 3.x 中运行良好,但它在 Python 2.x 中却无法正常工作,并会抛出一个 "string index out of range" 的错误。

2. 解决方案

要解决这个问题,我们需要对代码进行以下修改:

pos = [k + len(init_string) for k in pos]

在 Python 2 中,列表推导会将变量 i 的最后值泄漏到列表中,从而覆盖了初始化的值 0。因此,Python 2 将从索引 8 开始,这会导致后面的索引错误。

要修复此问题,只需将变量 i 重命名为其他名称即可:

pos = [k + len(init_string) for k in pos]

这样做就可以确保变量 i 的原始值保持不变。

代码示例

以下是修改后的代码示例:

def cellular_automaton(init_string, pattern, gens):
    values = [128, 64, 32, 16, 8, 4, 2, 1]
    pattern_list = []
    k = 0
    while k < len(values):
        if values[k] + sum(pattern_list) <= pattern:
            pattern_list.append(values[k])
        k = k + 1

    i = 0
    j = 0
    b = []
    f = ''

    pos_init = [0, 1, 0]
    pos_interm = []
    pos_init = [[n, n + 1, n] for n in range(len(init_string) - 1)]
    pos_interm.append(pos_init)
    pos_interm[-1][-1].append(len(init_string) - 1)
    pos_interm[-1][-1].append(0)
    pos_interm[0][0].insert(0, len(init_string) - 1)
    pos_interm2 = [val for subl in pos_interm for val in subl]
    pos = [val for subl in pos_interm2 for val in subl]

    b.append(pos)
    while j < gens:
        pos = [k + len(init_string) for k in pos]
        b.append(pos)
        j = j + 1
        c = [val for subl in b for val in subl]

    while i < len(c):
        if init_string[c[i]] == '.' and init_string[c[i + 1]] == '.' and init_string[c[i + 2]] == '.':
            if 1 in pattern_list:
                init_string = init_string + 'x'
            else:
                init_string = init_string + '.'
        elif init_string[c[i]] == '.' and init_string[c[i + 1]] == '.' and init_string[c[i + 2]] == 'x':
            if 2 in pattern_list:
                init_string = init_string + 'x'
            else:
                init_string = init_string + '.'
        elif init_string[c[i]] == '.' and init_string[c[i + 1]] == 'x' and init_string[c[i + 2]] == '.':
            if 4 in pattern_list:
                init_string = init_string + 'x'
            else:
                init_string = init_string + '.'
        elif init_string[c[i]] == '.' and init_string[c[i + 1]] == 'x' and init_string[c[i + 2]] == 'x':
            if 8 in pattern_list:
                init_string = init_string + 'x'
            else:
                init_string = init_string + '.'
        elif init_string[c[i]] == 'x' and init_string[c[i + 1]] == '.' and init_string[c[i + 2]] == '.':
            if 16 in pattern_list:
                init_string = init_string + 'x'
            else:
                init_string = init_string + '.'
        elif init_string[c[i]] == 'x' and init_string[c[i + 1]] == '.' and init_string[c[i + 2]] == 'x':
            if 32 in pattern_list:
                init_string = init_string + 'x'
            else:
                init_string = init_string + '.'
        elif init_string[c[i]] == 'x' and init_string[c[i + 1]] == 'x' and init_string[c[i + 2]] == '.':
            if 64 in pattern_list:
                init_string = init_string + 'x'
            else:
                init_string = init_string + '.'
        elif init_string[c[i]] == 'x' and init_string[c[i + 1]] == 'x' and init_string[c[i + 2]] == 'x':
            if 128 in pattern_list:
                init_string = init_string + 'x'
            else:
                init_string = init_string + '.'

        i = i + 3

    return init_string[(len(pos_interm2) + 1) * -2:(len(pos_interm2) + 1) * -1]

print(cellular_automaton('.x.x.x.x.', 17, 2))

现在,这段代码在 Python 2.x 和 Python 3.x 中都可以正常工作。