前言:
好早之前看到的一個邏輯題:有兩個2到99之間的整數,a知道這兩個數的和,b知道這兩個數的積。
第一句: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)
現在就只有唯一一個結果了。
輸出結果