前言:
好早以前看到的一个逻辑题:有两个2到99之间的整数,a知道这两个数的和,b知道这两个数的积。python
第一句:a对b说:我不知道这两个数是多少,但我确信你也不知道。程序
第二句:b说:我知道了。集合
第三句:a说:我也知道了。数字
问这两个数是多少? 题不难,只是手动去找没有python写程序找的快,并且用python程序能够在后面进行进一步的探索。
分析:
首先是a手上的数是两个数的和,那是在[4,198]之间。
第一句话分析:a确信b不知道这两个数
(1)
好比a手上的数字是8,那么要求的两个数字就有多是(2,6),(3,5),(4,4)这三种状况,对应的b手上的数字就多是12,15,16这三种状况,这是来自a的视角。
但简单分析,第一句话 a确信b不知道这两个数字是多少。那么b手上的数字确定不多是15,为何呢?由于15只有一种分解状况(两个素数相乘):3*5。若是b手上是15,那么b确定知道这两个数字是3和5了。
进而能够分析出 a 手上的数字确定不是8, 由于a手上是8的话,那b手上可能的三种状况(12,15,16) 其中的15这种状况,b是能够分析出这两个数字分别是多少的,而a确信b不知道,因此能够排除8。
进一步,那a手上什么数字能够排除掉呢?经过上面的分析,
能够得出 结论(1):a是不能分解成两个素数的和,凡是能够分解成两个素数的和的状况,b是能够知道这两个数的
上python代码:
asum1里面存了a手上还可能的数,54个(排除了那些能分解成两个素数的数)
(2)
上面的54个可能里面全是奇数,没有偶数。
进一步分析:a 手上的数字也不能写成(53+2x,x>=2)这种形式,由于若是能够分解成这种形式,b=532x,由于两个数是小于等于99的,532>99了,也只有一种分解状况53,2*x,进而b也知道这两个数字了。
因此结论(2):比上限/2(99/2=49.5)大的第一个素数(53),+3(56)之后的数字就排除了。
为何是+3,由于2*x最小是4.
因此通过第一句话后,a手上的数字asum2集合 还剩11个
[11, 17, 23, 27, 29, 35, 37, 41, 47, 51, 53] <-asum2
把他们分解了,相乘获得b的粗略集合:
第二句话分析:b知道了
b在什么状况下能够说这样的话呢?
好比b =24, 那么可能的分解(2,12),(3,8),(4,6)两种状况,那么对于的 a就是14,11和10三种状况,这是来自b的视角。
刚开分析了那么多得出a手上剩下的可能性:[11, 17, 23, 27, 29, 35, 37, 41, 47, 51, 53],这个集合的意思是当a手上是这些数的时候a才敢说第一句话,反言之a手上不是这些数时a就不敢说这些话。
那么24分解出来获得的 14,11和10三种状况:14,10不在a可能集合里,11在可能集合里。
11是惟一一个在a可能集合里的,因此b能够分析出a手上的数字是11,由于若是是其余两个数的话,a不敢说第一句话。
进而得出一个结论:b分解出来的全部两个数eg:(2,12),(3,8),(4,6)所组成的和eg:14,11和10, 有且只有一个存在在a的可能集合里
通过第二句话b手上可能数字有102个,存入bmul1
第三句话分析:a知道了
和第二句话如出一辙的分析,a为何能知道?惟一的可能性就是a手上的数的分解后组成的积有且只有一种状况在集合bmul1里(第二句话算出的集合b)
如今就只有惟一一个结果了。
输出结果