前言:
好早以前看到的一個邏輯題:有兩個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)
如今就只有惟一一個結果了。
輸出結果