我有一个输入文件,如下所示
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
不起作用,有什么方法可以解决这个问题?
答案 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个字符)。因此,您应该打印特定输入经过的所有状态,并寻找模式。
这个问题可能对您来说太难了,如果您认为编程实践对您来说更重要,那么您应该放弃它,或者在互联网上找到该算法的描述。再说一次,它不需要任何算法知识(除了诸如递归之类的基本知识),也不需要任何数学知识(除诸如奇偶性之类的基本知识之外),因此这是一个很好的练习。