这个「下意识」的背后是一群理科少年们迷恋的纸牌游戏:24。大概是高二的时候,我与几位同学一起到厦门双十中学参加数学夏令营,其中我还记得名字的有杜远志、吴奋强、林杰、杜明树、陈庆树。夏令营里上的是什么课我已经完全不记得,但我仍然清晰地记得:在临时宿舍里,一群少年拿着几副纸牌,热火朝天地比赛心算 24。
游戏规则很简单:拿一副完整的纸牌,剔除掉大王和小王,将剩下的纸牌平均分给比赛双方。双方各自手持一组纸牌,纸牌需背面朝上。每轮游戏开始,双方同时取出最上面的两张纸牌,反手甩到桌面上,四个数字同时出现在双方眼前。谁先算出 24,就怒拍床板,然后带着唾沫星子说出解法。先拍者先说。说对了,收入囊中;说错了,拱手送人。谁把对方手上的纸牌赢光,谁便胜出。
我的记忆里仍然有许多有意思的画面:比如我拍床板时太用力,疼得嗷嗷叫;又比如我算不过陈庆树,就找哥几个一起「三英战吕布」。我记得最经典的一道题,就是 "3、3、7、7",当时可是难倒了一众好汉,你想不想也试上一试? (解法在文末的代码块里)。
最终这 4 个数字一定会和 3 个二元运算符组成一个算式,而且这个算式一定可以用上面这种语法树表示。那么只要从剩余的数字中遍历所有可能的两数排列,再遍历可能的运算符,就可以递归地穷举出所有可能的语法树。因为减法和除法并不具备交换性,这里两数的顺序是需要考虑的,所以遍历的是两数的排列,而不是组合。