Python算法详解
上QQ阅读APP看书,第一时间看更新

3.1.2 实践演练——24点游戏

24点是一款经典的棋牌类益智游戏,要求四个数字的运算结果等于二十四。这个游戏用扑克牌更容易开展:拿一副牌,抽去大小王后(初练时也可以把J/Q/K拿去),剩下1~10这40张牌(以下用1代替A)。任意抽取4张牌(称为牌组),用加、减、乘、除(可加括号,高级玩家也可用乘方开方运算)把牌面上的数算成24。每张牌必须且只能用一次。例如抽出的牌是3、8、8、9,那么算式为(9−8)×8×3=24。

在下面的实例文件qiong.py中,演示了使用穷举法计算24点的过程。根据四个数和三个运算符,构造三种中缀表达式,要求遍历并计算每一种可能。显然可能的形式不止三种。但是,其他形式要么得不到24点,要么在加、乘意义上可以转换为这三种形式的表达式。

源码路径:daima\第3章\qiong.py

def twentyfour(cards):
    '''史上最短计算24点代码'''
    for nums in itertools.permutations(cards):  # 四个数
         for ops in itertools.product('+-*/', repeat=3):  # 三个运算符(可重复!)
              # 构造三种中缀表达式 (bsd)
              bds1 = '({0}{4}{1}){5}({2}{6}{3})'.format(*nums, *ops)  # (a+b)*(c-d)
              bds2 = '(({0}{4}{1}){5}{2}){6}{3}'.format(*nums, *ops)  # (a+b)*c-d
              bds3 = '{0}{4}({1}{5}({2}{6}{3}))'.format(*nums, *ops)  # a/(b-(c/d))
              for bds in [bds1, bds2, bds3]:  # 遍历
                   try:
                         if abs(eval(bds) - 24.0) < 1e-10:  # eval函数
                              return bds
                   except ZeroDivisionError:  # 零除错误!
                         continue
    return 'Not found!'
for card in cards:
    print(twentyfour(card))

执行后会输出:

((1+1)+1)*8
((1+1)+2)*6
(1+2)*(1+7)
((1*1)+2)*8
(1+2)*(9-1)
#省略后面的