问题描述:
已知小明的生日是下面几个日期之一,
5月15日,5月16日,5月19日
6月17日,6月18日
7月14日,7月16日
8月14日,8月15日,8月17日
小明把自己生日的“月”告诉了A,把自己生日的“日”告诉了B,然后让他们在不透漏自己所知答案的情况下推理小明的生日是哪天。
A说“我不知道小明的生日是哪天,但我肯定B也不知道。”
B说“我现在知道小明生日是哪天了。”
A说“我现在也知道小明生日是哪天了。”
由此可知,小明的生日是7月16日。
推理过程如下:
1)A说“我不知道小明的生日是哪天,但我肯定B也不知道。”
由此可知,月份肯定不是5或6,因为5月19日和6月18日中的19和18在所有数据中只出现了一次,如果是5月或6月的话,B是有可能只根据“日”来确定小明生日的。排除5月和6月之后,剩余的候选日期还有:
7月14日,7月16日
8月14日,8月15日,8月17日
2)B说“我现在知道小明生日是哪天了。”
此时,7月和8月有个共同的“日”是14,但是B说已经知道小明生日了,所以肯定不是14日。排除14日之后,剩余的候选日期还有:
7月16日
8月15日,8月17日
3)A说“那我也知道小明生日是哪天了。”
如果A知道的月份是8,那么他是无法知道剩余的8月份两个日期哪个是小明生日的,所以A知道的月份是7。剩余日期中只有一个是7月份的,所以最终确定小明生日是7月16日。
编写程序模拟上面的推理过程。函数func()接收一个字典birthday作为参数,其中元素的“键”表示月份、“值”表示日,要求模拟上面的推理过程并返回小明生日具体日期,如果无法推理出准确的日期就返回False。
参考代码:
运行结果: