题目
有4个囚犯,分别独立关在4个房间,实验时他们之间不能进行交流,相互也看不到对方,每天晚上随机一个人出来守夜,守夜的地方有一盏灯,守夜人每晚只能对灯进行一次操作(开/关),房间里的囚犯可以看到灯的情况;请设计一个规则(该规则会让所有囚犯都知道),确保有一个人知道每个人都出来守过夜。
解题
因为囚犯是不能进行交流的,所有的囚犯都不知道其它人是否出来守过夜,这里有两个需要记录的变量,一是当前守夜的人,二是不同守夜人的人数。
我们需要找一个人来统计守夜人的人数,需要囚犯之间不知道谁守过夜,但他们可以通过灯是否开着来判断是不是有没守过夜的人出来守夜了;然后我们还需要知道当前守夜的人,这个记录可以由囚犯自己来记录。所以我们可以定以下规则:
在4个囚犯中找一个囚犯来当计数人(假设是0号囚犯当计数人),计数人出来守夜只能“关灯”,如果灯是开着的,那就“关灯”,并且记录守夜人数+1,否则不进行操作;囚犯出来守夜只能“开灯”,如果灯是关着的,并且自己是第一次出来守夜,那就“开灯”,否则不进行操作。当计数人执行了4次“关灯”,那么就他就知道每个人都出来守过夜了。
代码
def func(n):
vigil_list = [False] * n # 记录自己是否守过夜
light = False # 灯的状态,False:关, True:开
counter = 0 # 0号囚犯是计数人
while False in vigil_list:
# 随机一个人出来守夜
a = random.randint(0, n - 1)
print(f"{get_name(a, counter)},{get_wake(vigil_list[a])},{get_light(light)}")
prisoner = vigil_list[a]
if a == counter and light: # 如果当前是"计数人",并且灯是开着的,那么"计数人"就关灯
vigil_list[a] = True
light = False
print("操作:关灯")
elif (not prisoner) and (not light): # 如果自己没守过夜,并且灯是关着的,那么囚犯就开灯
light = True
vigil_list[a] = True
print("操作:开灯")
def get_name(a, countor):
return "计数人" if a == countor else f"{a}号囚犯"
def get_wake(prisoner):
return "守过夜" if prisoner else "没守过夜"
def get_light(bool):
return "灯是开着的" if bool else "灯是关着的"