美文网首页
算法思维训练逻辑任务(18) 谁偷了钻石

算法思维训练逻辑任务(18) 谁偷了钻石

作者: Python_Camp | 来源:发表于2022-08-26 12:46 被阅读0次

    逻辑推理任务。
    珠宝店失窃,能够确定是员工内盗。共四名员工对侦探的回答:
    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'

    相关文章

      网友评论

          本文标题:算法思维训练逻辑任务(18) 谁偷了钻石

          本文链接:https://www.haomeiwen.com/subject/birfnrtx.html