原标题:超级加倍!学会了就是一代土块(du guai)——你知道有多少种洗牌的方式吗?

数学中有一个非常可爱的函数——阶乘函数( factorial function),它会将输入数乘以所有小于它的正整数。例如,factorial (5) = 5×4×3×2×1 = 120。通常阶乘的结果惊人地庞大,顺其自然地,阶乘简记为一个感叹号。当一个数学家写下5! = 120或者13! = 6,227,020,800时,感叹号既代表阶乘,也传达了兴奋之情。

阶乘在数学中备受关注有很多原因,其中一个最普遍的原因是它代表了打乱物品方法的总数。假如你有 13 张扑克要洗,那么第一张牌就有13 种可能,第二张就剩下12 种可能,第三张剩下11 种可能,以此类推。仅仅13 张牌就有超过60 亿种排列方式。

对于一副包含 52 张牌的扑克,数字非常庞大。手动计算52! 会花费很长时间,这就是最适合让计算机帮我们的事了。为了让计算机帮我们干活,你需要将计算过程表达成一个计算机可以执行的算法。下面便是我写的一系列指令,将输入数乘以所有小于它的数。

步骤 1:将初始值 n 设置为运行结果。

步骤 2:将 n 减去 1。

步骤 3:将运行结果乘以新的 n。

步骤 4:重复步骤 2 和步骤 3,直到 n 减小至 1。

步骤 5:返回运行结果。

计算 52! 时,我们可以试着按照算法手动执行前几个循环:

我们只运行了6 个循环,运行结果已经超过了140 亿!(这个感叹号不是阶乘的意思,我只是想强调这些数字增长得多快。)这绝对是我们希望计算机为我们做的那种冗长的计算。最后一步是将算法翻译成计算机能够接受的语言。

对于计算机而言,算法是什么样的?正如人类可以说不同的语言,计算机也可以明白不同的编程语言。我选择了 Python 语言,因为它的语法非常简单,也是最接近英语的计算机语言之一。在程序中,我还在右侧添加了注释,以解释每一行代码的作用。

下面就是我用 Python实现的阶乘算法。如果你愿意,不妨在计算机上运行一下。与我们之前命名函数的方式类似,我们可以赋予每个算法一个名字,然后在旁边的括号中写上要输入的东西。

我再三检查了这个程序,确保它可以正常运行。我将这个程序载入到计算机中,输入“factorial (13)”来验证 13!。6,227,020,800 再次出现在我的屏幕上。于是我计算了 52!,屏幕上的结果如下:

>>>factorial(52)

这是一个包含 68 位数字的数,是一个真正庞大的数。也就是说,我们有8,000 亿亿亿亿亿亿亿亿种方式来洗52 张扑克牌。可观测宇宙中只有1 亿亿亿颗恒星;我们的宇宙目前的年龄是40 亿亿秒。

这意味着,即使每一颗恒星都有 10 亿颗行星,每颗行星上有10 亿个外星人,每个外星人从宇宙诞生开始以每秒10 亿次的速度洗牌,我们现在最多只能洗完所有可能方式的一半。这只是52 张牌,幸亏我们还没有加入大小王!

无论如何,我们现在知道答案是什么了。我们还可以用另外一种方法计算:递归算法。我们只需要用这个算法本身来描述算法,例如:“n 的阶乘就是n 乘以n-1 的阶乘。” 唯一还需要知道的就是,1 的阶乘是1 这是算法中的“ 退出条款” ,可以防止递归无限地进行下去。

步骤 1:注意 1 的阶乘等于 1。

步骤 2:n 乘以 n-1 的阶乘。

翻译成 Python 语言:

拿到“factorial (13)” 后,我的计算机便开始生成递归链,直到它计算factorial (1) ,然后返回,最终输出6,227,020,800 。同样,运行“factorial (52)” 会输出包含68 位数字的怪物。实际上我并没有告诉程序到底如何计算阶乘,只是告诉程序一个数的阶乘是如何与更小的阶乘联系在一起的。再一次,递归算法展现了它的魔力:从看似空洞的代码中变出答案。现在有两个不同的程序以不同的方法计算出相同的答案。

于是我们只有一个选择:让它们竞争!我花费了一小段时间,同时运行这两个算法,进行比赛:最先计算出 100 阶乘的算法 获胜。计算出100! 的全部158 位数字,递归的Python 程序花费了0.000068 秒,而普通的算法只用了0.000046 秒。因此,毫无疑问,非递归算法取得了胜利!

然而,递归算法并不是总输给显式算法,这取决于算法计算什么,递归算法非常适合于计算某些问题。最后,我们利用递归算法算算移动圆盘的祭司们需要多长时间才能引发世界末日。每移动一个圆盘到目标柱,需要将其上方的所有圆盘移动两次,所以每增加一个圆盘,总移动次数就要变成原来的 2倍,再外加一步将最底圆盘移动到目标柱,所以将含有n个圆盘的塔移到目标柱所需的步数是移动n-1个圆盘的步数的2倍再加1。

因此,如果你有 10 个圆盘,就需要移动1,023 次(这个数其实就是210-1 ,是一个梅森数!所有形如2n -1 的数都是梅森数,即使它们不是素数)。如果每秒移动一步,那么需要大约17 分钟来完成所有的移动。

即使一个人将一生的所有时间全部用于移动圆盘,最多只能完成包含 31 个圆盘的汉诺塔的移动。所以如果一个人的空闲时间比较多,那么包含32 个圆 盘的汉诺塔是一个不错的礼物。与完成100 亿张牌的魔术相比,完成这个“ 快速游戏” 所需的时间长多了。

标准的国际象棋棋盘有64 个方格,所以麦粒总数恰好是移动64 个圆盘的汉诺塔所需的步数——超过 1,800 亿亿。

这是一个庞大的数字,即使祭司在 46 亿年前太阳系刚形成的时候就开始搬运圆盘,每秒钟移动50 步,从现在开始向后推50 亿年,他们依然无法完成这项工作。到那时,太阳将变成一个红巨星,将地球吞噬。所以我想,现在我们很安全。

(点击书封即可购买哦!)

《我们在四维空间可以做什么》

著者

[澳]马特·帕克 (Matt Parker)

审校

顾森( Matrix67)

听会说脱口秀的数学家讲一场克服数学恐惧症的数学栋笃笑返回搜狐,查看更多

责任编辑:

python棋盘放麦粒求和递归_超级加倍!学会了就是一代土块(du guai)——你知道有多少种洗牌的方式吗?...相关推荐

  1. python棋盘放麦粒求和递归_Python递归调用实现数字累加的代码

    我就废话不多说了,直接上代码吧! def sum_numbers(num): # 1.出口 if num == 1: return 1 # 2.数组累加 temp = sum_numbers(num ...

  2. python棋盘放麦粒_棋盘上的麦粒有什么问题?

    展开全部 在印度有一个古老的传说:舍罕王打算奖636f70793231313335323631343130323136353331333431346364赏国际象棋的发明人--宰相西萨·班·达依尔. ...

  3. python棋盘放米的故事阅读答案_棋盘摆米的故事你得到了什么启发

    就是这个:棋盘上的米有这样一个关于某一个古代国王的故事.国王爱上了一种称为"围棋"的游戏,决定嘉奖此项游戏的发明者.他把发明者召入宫中并且当众宣布要满足发明者一个愿望." ...

  4. python123中棋盘放米的故事_小学数学故事:棋盘上的麦粒问题

    第 1 页 小学数学故事:棋盘上的麦粒问题 查字典数学网为大家提供了数学故事棋盘上的麦粒问 题,希望同学们多多积累,不断进步 ! 在印度有一个古老的传说:舍罕王打算奖赏国际象棋的发明 人 -- 宰相西 ...

  5. python123中棋盘放米的故事_棋盘里放麦粒的故事你只知道一半

    01 - 印度国王的赏赐 古时候,印度有个国王很爱玩.一天,他对大臣们说:希望得到一种玩不腻的玩意儿,谁能使他得到,将重重有赏. 不久,有个聪明的大臣向他献上一种棋子,棋盘上有64个格子,棋子上刻着& ...

  6. python棋盘放米问题_棋盘堆米的难题怎么解决?

    原标题:棋盘堆米的难题怎么解决? 国外有个故事,一个人和国王打赌.如果国王输了就给他米.但是他要的你看上去很少,实则算起来确实非常多,甚至一个国家的米都不够.国王为了用人信守承诺.国王为了应向所有人显 ...

  7. python棋盘放米循环结构_Python递归法计算棋盘上所有路径总奖品最大值(京东2016编程题)...

    问题描述:假设有一个6x6的棋盘,每个格子里有一个奖品(每个奖品的价值在100到1000之间),现在要求从左上角开始到右下角结束,每次只能往右或往下走一个格子,所经过的格子里的奖品归自己所有.问最多能 ...

  8. python棋盘放米问题_Python基于回溯法子集树模板解决马踏棋盘问题示例

    本文实例讲述了Python基于回溯法子集树模板解决马踏棋盘问题.分享给大家供大家参考,具体如下: 问题 将马放到国际象棋的8*8棋盘board上的某个方格中,马按走棋规则进行移动,走遍棋盘上的64个方 ...

  9. java等差数列求和递归_[编程题] 递归实现等差数列–招银面试题1

    [编程题] 递归实现等差数列–招银面试题1 递归实现等差数列–招银面试题 题目描述 使用递归实现一个球等差数列的和,要求,输入首项a,公差d,数列长度n,求出sum 示例 例如: 输入: 1 1 3 ...

最新文章

  1. ios 百度地图指定区域_iOS开发(第三方使用)——百度地图的简单使用(定位与当前位置的显示)...
  2. 编译 android 内核,编译内核  |  Android 开源项目  |  Android Open Source Project
  3. C语言定义一个头节点,一个关于C语言链表头结点的问题
  4. Win7系统不能录音怎么办
  5. Ubuntu16.04 sudo apt-get install lib***-dev安装失败,无法锁定文件,sudo apt-get update 更新失败也无法解决
  6. Apache ServiceComb 开源两周年,聊聊其与微服务的前世今生
  7. 计算机工程学院迎新晚会,计算机与信息工程学院2016级迎新晚会举行
  8. 选择多级分类_商用车齿轮油的选择与运用!!
  9. linux系统管理考试试题及答案,Linux系统管理一测试题-附答案
  10. unity 陀螺仪控制节点旋转
  11. 车牌识别算法_易泊车牌识别算法助力智慧城市交通
  12. 我的随身电脑-千脑(转载)
  13. Nexus3搭建本地仓库
  14. 十进制与二进制、八进制、十六进制对照表
  15. Android内容提供者(Content provider)
  16. 【EXCEL】 EXCEL VBA SQL UPDATE:操作必须使用一个可更新的查询
  17. Python pandas.DataFrame.combine_first函数方法的使用
  18. 这个毕业季,让海马体照相馆为简历添“战斗力”
  19. DDD领域驱动设计浅谈
  20. 本地搭建自己的电影网站,并发布公网访问 3-3

热门文章

  1. 安全牛课堂课程自动播放下一集以及全屏
  2. 航空发动机原理复习之计算题总结(四)
  3. TI AM335x 可编程实时模块(PRUSS)详解
  4. Thinkphp6.0+vue个人虚拟物品发卡网站源码
  5. 程序设计:用C语言写一个单词本程序
  6. String类型日期格式从yyyy-MM-dd HH:mm:ss转换成yyyy-MM-dd‘T‘HH:mm:ss.SSSXXX
  7. Termius首次连接腾讯云服务器实例
  8. quartz 配置文档
  9. ubuntu18.04亮度无法调整时,安装brightness-controller的两种方式
  10. 证书管理机构——CA