Python运行时错误无法按预期工作

时间:2019-06-21 15:50:27

标签: python python-3.x python-2.7 error-handling runtime-error

我有一个输入文件,如下所示

3
01
0010100
11011

输出应该看起来像这样

LIVES
DIES
LIVES

但是我的代码返回了,

DIES
[1, 0]
DIES
[0, 1, 0, 0, 0, 1, 0]
DIES
[1, 1, 0, 1, 1]

我正在解决此问题(https://open.kattis.com/problems/whowantstoliveforever)。基本上,我正在查看位置i-1和i + 1上的位的当前值(如果存在);否则假定它们为0)。如果我的程序恰好看到一个1,则第i个位的下一个值为1,否则为0。所有位立即更改,因此下一个状态中的新值仅取决于前一个状态中的值。如果宇宙仅包含零,则该宇宙已死亡。

我想说的是,如果程序陷入无限循环,这可能意味着宇宙将继续存在,0和1将继续重复。如果len(set(x))为1,则我返回False。

import sys


def get_bit(bits, i):
    if 0 <= i < len(bits):
        return int(bits[i])
    else:
        return 0


def print_result(boolean):
    print("LIVES" if boolean else "DIES")


def recursion(in_list, output_list):
    try:
        for index in range(len(in_list)):
            if (get_bit(in_list, index-1) == 0 and get_bit(in_list, index+1) == 0) or (get_bit(in_list, index-1) == 1 and get_bit(in_list, index+1) == 1):
                output_list.append(0)
            elif(get_bit(in_list, index-1) == 0 and get_bit(in_list, index+1) == 1) or (get_bit(in_list, index-1) == 1 and get_bit(in_list, index+1) == 0):
                output_list.append(1)
        if len(set(output_list)) == 1:
            return False
        else:
            in_list = output_list
            output_list = []
            recursion(in_list, output_list)
    except RuntimeError:
        return True


num_cases = int(sys.stdin.readline().strip())
for i in range(num_cases):
    _list = []
    case = sys.stdin.readline().strip()
    for char in case:
        _list.append(char)
    output_list = []
    print_result(recursion(_list, output_list))
    print(output_list)

如果except RuntimeError不起作用,有什么方法可以解决这个问题?

2 个答案:

答案 0 :(得分:0)

由于一些原因,依靠递归限制是不理想的。但是主要的算法“如果它可以生存X代,那么它就可以永远存在”,从根本上讲,它不会为更长的输入而削减它。

这是我实现此方法的框架:

def get_new_state(old_state):
    pass # todo: implement

def is_dead(state):
    pass # todo: implement

def determine_fate(state):
    seen = set()       
    while True:
        if is_dead(state):
            return "DIES"
        if state in seen:
            return "LIVES"
        seen.add(state)
        state = get_new_state(state)

我正在使用一套记忆旧状态。如果我们不只一次看到一个状态,则说明已经陷入循环或稳定状态,因此我们知道结果是“ LIVES”。如果在达到空状态之前没有发生这种情况,那么我们知道结果是“ DIES”。

请注意,由于列表不可散列,因此不能添加到集合中,因此必须从使用列表表示状态转变。我会使用字符串。

答案 1 :(得分:0)

首先,@ Blorgbeard是正确的,请不要这样做。这是一个可怕的反模式。


但是要回答您的名义问题:即使是小情况,您的代码片段也无法使用的原因是您进行递归的方式:

recursion(in_list, output_list)

如果宇宙存在,那么在某个时候,它确实会抛出RuntimeError(更确切地说是RecursionError),以超过递归限制(不是很大;在我的测试环境中为2961) ,因此不要指望它能正确解决任何大型实例)。这意味着此调用的某些实例将返回True。但是,该返回值是看不见的,并且封闭函数在不返回任何内容的情况下结束,这意味着它返回了None

要正确地捕获RecursionError,可以将try-catch块放在递归函数之外,或者像这样将所需的任何值传递到堆栈中:

return recursion(in_list, output_list)

这为您提供的小包装箱提供了正确的返回值。


但是,您真正应该做的是认识到您尚不知道一种有效的算法来解决此问题(问题说明在每种输入情况下最多可以使用200000个字符)。因此,您应该打印特定输入经过的所有状态,并寻找模式。

这个问题可能对您来说太难了,如果您认为编程实践对您来说更重要,那么您应该放弃它,或者在互联网上找到该算法的描述。再说一次,它不需要任何算法知识(除了诸如递归之类的基本知识),也不需要任何数学知识(除诸如奇偶性之类的基本知识之外),因此这是一个很好的练习。