打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
网友过招老杨:Gauss和Poincare数学问题的另类解法

大家应该还记得前几天我们的一篇文章:用SQL解一道有趣的数学题:Gauss和Poincare ,错过的朋友请先回顾。感谢网友的反馈,发来新的解法一则。

如网友所言:这个解法并没有颠覆性原解法,只是在一些数学逻辑上稍微有些不同,体现在SQL建模上的少许不同。

问题提出

这是一个流传已久的故事:

Gauss和Poincare在天堂相遇了,上帝说:你们都是人间最伟大的数学家,那我来出道题考考你们谁更聪明。我在左手写一个大于1小于100的数,在右手同样写一个大于1小于100的数,然后把他们的和写在Gauss手上,把积写在Poincare手上,看看你们能不能猜出这两个数字是几。

Gauss看了手上的数字,说:“我不知道这两个数字是几,可我保证Poincare也不知道。”

Poincare看了手上的数字,说:“我原来的确不知道那两个数字是几,可我现在知道了。”

Gauss说:“那我也知道了。”

问题:那两个数字是几?

网友新解

先看SQL逻辑和结果:

SQL> WITH T_NUM AS

  2   (SELECT ROWNUM + 1 NUM FROM DUAL CONNECT BY LEVEL < 99)

  3  SELECT A, B

  4  FROM

  5  (

  6  SELECT A, B,TOTAL,MUL,MUL_M,

  7     COUNT(DECODE(MUL_M, 1, 1)) OVER (PARTITION BY TOTAL) MUL_N

  8  FROM

  9  (

 10  SELECT A, B,TOTAL,MUL,MUL_M

 11   FROM

 12   (

 13   SELECT

 14   A,

 15   B,

 16   MUL,

 17   TOTAL,

 18   COUNT(TOTAL) OVER (PARTITION BY MUL) MUL_M

 19   FROM

 20     (

 21       SELECT

 22             A,

 23             B,

 24             A + B TOTAL,

 25             A * B MUL

 26           FROM

 27             (SELECT A.NUM A,

 28                     B.NUM B

 29                     FROM T_NUM A, T_NUM B

 30                     WHERE  A.NUM+B.NUM-2 in(

 31  SELECT  NUM

 32  FROM

 33  (

 34  SELECT A.NUM * B.NUM NUM FROM T_NUM A, T_NUM B

 35  WHERE A.NUM <= B.NUM

 36  AND A.NUM > 1

 37  AND B.NUM > 1

 38  )

 39  WHERE MOD(NUM,2)=1 AND NUM < 99

 40  )

 41  AND A.NUM < B.NUM

 42             )

 43  )

 44  )

 45  WHERE MUL_M=1

 46  )

 47  )

 48  WHERE MUL_N = 1;

         A          B

---------- ----------

         4         13

剖析说明如下

高斯知道两数之和,不知道两数之积,但却可以肯定的说庞加莱不知道两数是什么。这说明两数之和决定了其对应的两数之积不可能分解为两个素因子。而根据哥德巴赫猜想(没错,就是陈景润做出了至今最好成绩中国人耳熟人详的那个猜想):任一大于2的偶数都可以写成两个素数之和。

这也就是说高斯看到的那个两数之和肯定不是偶数,一定是一个奇数。而一个奇数要写成两个素数的和,一定要包含2这个最小的素数,所以两数之和只要是2+奇合数的形式就一定不能表示成两个素数之和的形式。

分析下最内层的SQL: 

 21       SELECT

 22             A,

 23             B,

 24             A + B TOTAL,

 25             A * B MUL

 26           FROM

 27             (SELECT A.NUM A,

 28                     B.NUM B

 29                     FROM T_NUM A, T_NUM B

 30                     WHERE  A.NUM+B.NUM-2 in(

 31  SELECT  NUM

 32  FROM

 33  (

 34  SELECT A.NUM * B.NUM NUM FROM T_NUM A, T_NUM B

 35  WHERE A.NUM <= B.NUM

 36  AND A.NUM > 1

 37  AND B.NUM > 1

 38  )

 39  WHERE MOD(NUM,2)=1 AND NUM < 99

 40  )

 41  AND A.NUM < B.NUM

 42             )

这一层的意思是构造出所有的两数之和减2的结果是奇数且是合数的所有可能性。到了这一步,高斯看到的两数之和就可以肯定的说,庞加莱一定不知道这两个数是什么。

 接下来的一步,实现庞加莱知道了两个数是什么。

 10  SELECT A, B,TOTAL,MUL,MUL_M

 11   FROM

 12   (

 13   SELECT

 14   A,

 15   B,

 16   MUL,

 17   TOTAL,

 18   COUNT(TOTAL) OVER (PARTITION BY MUL) MUL_M

 19   FROM

 20     (

 21       SELECT

 22             A,

 23             B,

 24             A + B TOTAL,

 25             A * B MUL

 26           FROM

 27             (SELECT A.NUM A,

 28                     B.NUM B

 29                     FROM T_NUM A, T_NUM B

 30                     WHERE  A.NUM+B.NUM-2 in(

 31  SELECT  NUM

 32  FROM

 33  (

 34  SELECT A.NUM * B.NUM NUM FROM T_NUM A, T_NUM B

 35  WHERE A.NUM <= B.NUM

 36  AND A.NUM > 1

 37  AND B.NUM > 1

 38  )

 39  WHERE MOD(NUM,2)=1 AND NUM < 99

 40  )

 41  AND A.NUM < B.NUM

 42             )

 43  )

 44  )

 45  WHERE MUL_M=1

这一步根据两数之积分组后的两数之和只有一种可能性的,也就是MUL_M=1,于是庞加莱就知道了,这两个数是什么。

最后一步,在上一步两数之积只有一种可能性的情况下,两数之和只有一种可能性的,也就是MUL_N=1,于是高斯也知道了这两个数是什么。

注意这个结果是正确的,思路也非常巧妙。于是杨长老忍不住技痒,再次操刀,就有了以下的改变。

杨长老对答

杨长老评价:能利用数学知识和算法来进行解题非常难得。

提几个小的问题:

1.在构造数组的时候已经排除了A和B等于1的情况

 WITH T_NUM AS

   (SELECT ROWNUM + 1 NUM FROM DUAL CONNECT BY LEVEL < 99)

因此36行和37行的判断不需要:

AND A.NUM > 1

AND B.NUM > 1

2.通过数学算法可以过滤掉一部分数据,可惜SQL上实现过滤的方法比较复杂,反而造成了更多的嵌套,单次执行逻辑读接近5000,根据楼主的含义进行了一下改写,逻辑读可以降到230左右:

WITH T_NUM AS

 (SELECT ROWNUM + 1 NUM FROM DUAL CONNECT BY LEVEL < 99), 

 T_ALL AS

 (SELECT A.NUM A, B.NUM B, A.NUM + B.NUM TOTAL, A.NUM * B.NUM MUL 

 FROM T_NUM A, T_NUM B

 WHERE A.NUM <= B.NUM)

SELECT A, B

FROM

(

SELECT A, B,TOTAL,MUL,MUL_M,

   COUNT(DECODE(MUL_M, 1, 1)) OVER (PARTITION BY TOTAL) MUL_N

FROM

(

SELECT A, B,TOTAL,MUL,MUL_M

 FROM

 (

 SELECT

 A,

 B,

 MUL,

 TOTAL,

 COUNT(TOTAL) OVER (PARTITION BY MUL) MUL_M

 FROM

   (

     SELECT * 

     FROM T_ALL

     WHERE A != B

     AND TOTAL - 2 IN 

     (

     SELECT MUL 

  FROM T_ALL

  WHERE MOD(A, 2) = 1

  AND MOD(B, 2) = 1

  AND MUL < 99

  )

)

)

WHERE MUL_M=1

)

)

WHERE MUL_N = 1;

不仅要实现功能,还是关注性能,这是SQL开发的精髓所在。

大家可以体验一下杨长老的强大底蕴和功力,而云和恩墨SQL审核产品和服务正是致力于提升SQL性能,改善用户体验。

如果你有更好的解答,并且对SQL感兴趣,请给我一份简历:eygle@enmotech.com .

如何加入"云和恩墨大讲堂"微信群
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
鬼谷子猜数 - 智力题的巅峰之作,奥数只是渣渣
鬼谷子算术
古老的数学问题
关于分解因数问题的奥数题
1.4 素数,合数与分解素因数
小学1
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服