重庆思庄Oracle、Redhat认证学习论坛

标题: SQL解决生活中的数学问题 [打印本页]

作者: 王硕    时间: 2016-1-23 20:23
标题: SQL解决生活中的数学问题
求解:
一筐鸡蛋:
1个1个拿正好拿完。
2个2个拿还剩1个。
3个3个拿正好拿完。
4个4个拿还剩1个。
5个5个拿还剩4个。
6个6个拿还剩3个。
7个7个拿正好拿完。         
8个8个拿还乘1个。         
9个9个拿正好拿完。
问筐里有多少鸡蛋?

文科生 用文科的算,学计算机的你们怎么算呢?


作者: 王硕    时间: 2016-1-23 20:24
SQL> select n from (select level n from dual connect by level <1000000) where mod(n,2)=1
  2  and mod (n,3)=0
  3  and mod (n,4)=1
  4  and  mod (n,5)=4
  5  and mod(n,6)=3
  6  and mod(n,7)=0
  7  and mod(n,8)=1
  8  and mod(n,9)=0;

         N
----------
      1449
      3969
      6489
      9009
     11529
     14049
     16569
     19089
     21609
     24129
     26649

         N
----------
     29169
     31689
     34209
     36729
     39249
     41769
     44289
     46809
     49329
     51849
     54369

         N
----------
     56889
     59409
     61929
     64449
     66969
     69489
     72009
     74529
     77049
     79569
     82089

         N
----------
     84609
     87129
     89649
     92169
     94689
     97209
     99729
    102249
    104769
    107289
    109809

         N
----------
    112329
    114849
    117369
    119889
    122409
    124929
    127449
    129969
    132489
    135009
    137529

         N
----------
    140049
    142569
    145089
    147609
    150129
    152649
    155169
    157689
    160209
    162729
    165249

         N
----------
    167769
    170289
    172809
    175329
    177849
    180369
    182889
    185409
    187929
    190449
    192969

         N
----------
    195489
    198009
    200529
    203049
    205569
    208089
    210609
    213129
    215649
    218169
作者: 王硕    时间: 2016-1-23 20:44
本帖最后由 王硕 于 2016-1-23 20:46 编辑

杨廷琨 - 用SQL解析神奇的扑克牌魔术
原创 2016-01-22 杨廷琨 Oracle



从一副扑克牌中随意抽取21张牌。让观众从这些牌中随意选择一张,这张牌就是最后通过魔术需要找到的目标牌。让观众牢记后将其放回到其余20张牌中,然后任意洗牌。
下面开始进行发牌的工作,发牌和普通扑克的发牌规则一样。将牌发成3叠,每叠7张。将每叠牌依次展示给观众,要求观众确认目标牌在3叠的哪一叠中即可。
之后将3叠牌合在一起,将包含目标牌的一叠放在其他两叠牌中间。注意此时不要打乱每叠牌的顺序。
然后再次发牌,和刚才完全一样,还是将牌发成3叠。让对方确认目标牌所在的一叠,将这叠牌放到另外两叠牌的中间。
最后,再次重复上面的发牌、确认此过程,仍然将包含目标牌的那叠牌,放到另外两叠牌的中间。
下面神奇的时刻到来了:从这叠扑克牌的上面每次拿起一张,每拿起一张牌的同时要说一句话:“你要相信魔术你的牌是”。说完这句话,下一张牌就是目标牌了。


看上去这个魔术很神奇,而且最神奇的是,这个魔术任何人都可以来表演。这就说明无论这张牌最初在哪个位置,只要按照这个规则最后都一定会来到这个指定的位置。
SQL求解

看了这个魔术,不禁有点手痒,既然是DBA出身,就用SQL来演示一下这个魔术的过程吧,见如下代码:

SQL> WITH A AS
2 (SELECT ROWNUM P FROM DUAL CONNECT BY LEVEL <= 21)
3 SELECT
4 7 + CEIL(
5 (7 + CEIL(
6 (7 + CEIL(P/3))
7 /3))
8 /3)
9 FROM A;
7+CEIL((7+CEIL((7+CEIL(P/3))/3))/3)
-----------------------------------
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
已选择21行。
详细解析SQL逻辑

解释一下这个SQL:

设WITH查询中的P表示这张牌的初始位置,这个位置的取值范围是从1到21。而后将牌按照发牌的顺序分成3份,于是这张牌的位置变为CEIL(P/3)。由于在魔术表演的过程中,目标牌所在的那一叠牌会放在其他两叠牌的中间,也就是说目标牌的前面增加了7张牌,因此目标牌的位置要增加7。


魔术中上面的步骤重复了3次,因此在SQL中这个过程也重复3次,最终SQL返回的结果就是目标牌21种不同初始位置所对应的魔术结束时刻目标牌的最终位置。


根据计算结果可以看到,无论这张牌在哪里,最终都会达到第11张的位置。这也就是这个魔术的奥秘之所在。


不过SQL只是演示了结果,并没有给出为什么会出现这种结果的答案,下面通过数学手段简单分析一下:


由于第一次平均分的时候这张牌的位置是任意的,所以这次平均分的意义不大。这次平均分的目的只是将目标牌的那一份放到中间的位置。所以可以认为这张牌在中间位置第1到7的任何一个位置上,因此这张牌的位置就是7 + p。下面将牌分成三份,然后将目标牌堆放到中间,这时这张牌的位置变为7 +(7+p)/3。最后再重复一次这个动作,最终结果变为:7 + (7 + (7+p)/3)/3。


对上面的表达式进行通分计算后,结果变成(7*9 + 7*3 + 7 + p)/9,进一步简化变成(91 +p)/9,最后变成了10 + (1+p)/9,而p的位置是1到7,也就是说无论取何值,(1+p)/9都不会大于1,所以最终的结果是11。


最后,应该修改一下魔术中咒语:“你要相信数学你的牌是”。








欢迎光临 重庆思庄Oracle、Redhat认证学习论坛 (http://bbs.cqsztech.com/) Powered by Discuz! X3.2