逻辑推理任务。
珠宝店失窃,能够确定是员工内盗。共四名员工对侦探的回答:
A:我没有偷钻石。B:D是一个罪犯。C:B是偷窃这颗钻石的罪犯。D:B有动机陷害我。
假设已经掌握的情况看,只有一个人说真话,但不知道具体是谁说真话。那么能否决定了谁偷了这颗钻石。
答案是:说真话的是D,罪犯是A,逻辑思维过程枚举每个人说真话而其他人说假话。
分析思路
首先,A、B、C、D四个人都是犯罪嫌疑人,我们把这四种可能性放到一个列表中 state = ["A"、"B"、"C"、"D"]。然后再去看这四种情况,可以知道4个人中只有一个人说的是真话,所以我说这四个人说。
A:我没有偷钻石。犯罪者不是一个 代码表示 state['A']! = not "A"
B:D偷钻石。代码表示 state['B'] == "D"
C:B偷钻石。理解:罪犯是B 代码表示 state ['C'] == "B"
D:B陷害我。B是错误的,罪犯不是D 代码表示 state['D']! = not "D"
遍历每个人说真话,其他3人说假话
def find(state, true_man):
for x in range(len(state)):
#遍历一个人说真话,其他3人说假话
states = (state[x]!="A"),
(state[x]=="D"),
(state[x]=="B"),
(state[x]!="D")
if sum(states) == true_man:
return ("Criminals are:% s" %state[x])
true_man = 1 #Number of people saying
state = ["A", "B", "C", "D"]
#Who is the 4 cases of criminals?
print(find(state, true_man))
Criminals are:A
在上面例子中,枚举每个人说真话,其他人说假话,只有一种情况满足题目中的约束条件:只有D说真话时,4个人中有三个人说谎。我们可以稍微修改上述代码获取遍历的每一步结果:
def find(state, true_man):
for x in range(len(state)):
#遍历一个人说真话,其他3人说假话
states = (state[x]!="A"),
(state[x]=="D"),
(state[x]=="B"),
(state[x]!="D")
print(states)
if sum(states) == true_man:
return ("Criminals are:% s" %state[x])
true_man = 1 #Number of people saying
state = ["A", "B", "C", "D"]
输出:
[False, False, False, True]
[True, False, True, True]
[True, False, False, True]
[True, True, False, False]
上述任务难度升级 ****
在上面例子中,如果已知是2人、或者3人说真话,那么又该如何找到谁是窃贼?
枚举['A','B','C','D'] 四人中说真话或假话的所有可能情况,考虑这种方式:
['1','0','0,'0'] 代表四人中只有‘A’说真话,其他三人说谎;
依此类推可以用二进制穷举所有情况。
函数statement(person) 运用字典结构初始化每个人的申明:
values是包含2个元素的列表, 角标位置为 0 :此人说谎 角标位置为 1:此人说真话
输出 字典结构sates.keys是['A','B','C','D']
def statement(person):
states = dict(zip(person,[]*len(person)))
states['A'] = ['A',['B','C','D']]
states['B'] = [['A','B','C'],"D"]
states['C'] = [['A','C','D'],"B"]
states['D'] = ['D',['A','B','C']]
return states
person = ['A','B','C','D']
print(statement(person))
主函数 find(state, true_man) 函数find传入参数state是子函数statement返回结果 缺省true_man时,则返回所有遍历结果
def find(state, true_man):
enum = range(int('0b0000',2),int('0b1111',2)+1)
status = ['{:0>4}'.format(bin(i)[2:]) for i in enum]
key = list(state.keys())
ans = {}
for elem in status:
sets = set(state[key[0]][int(elem[0])])
for i, c in enumerate(elem):
sets &= set(state[key[i]][int(c)])
ans[elem] = set(sets)
return [[k,v] for k,v in ans.items() if len(v)]
states = statement(person,states={})
print(find(states,true_man=1))
[['0001', {'A'}], ['1001', {'C'}],
['1011', {'B'}], ['1100', {'D'}]]
输出结果又一次支持结论:已知只有一个人说真话的前提下,只有['0001', {'A'}符合
若有2个人说谎,2人说真话,那么 窃贼只会在'C'和‘D'之间的某一个;
若有1个人说谎,3人说真话,那么 窃贼只能是'B'
网友评论