Python实现快速计算24点游戏的示例代码

 更新时间:2022年12月02日 08:17:04   作者:小小明-代码实体  
这篇文章主要为大家详细介绍了Python如何实现快速计算24点游戏并获取表达式,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下

24 点游戏规则

有4个范围在 [1,9] 的数字,通过「加、减、乘、除」四则运算能够获得24,认为有解。

4个范围在 [1,9] 的数字能够产生495种可能,其中404中组合情况都是有解的,有解概率高达81.62%。

下面我们用python来验证它,首先计算组合数:

from scipy.special import comb

comb(9, 4, repetition=True)

495.0

可以看到python计算出9个数字有重复的组合情况数是495。

下面我们需要一个方法,判断4个数字能否组合成为24点,这里我采用回溯算法进行计算。

回溯算法计算思路

首先从4个数字中选择2个数字,然后再选择一种运算操作,然后用得到的结果取代选出的2个数字。然后在剩下的3个数字中,进行同样的操作。依次类推,最终计算到只剩一个数字,看结果是否为24即可。

开始编码:

from operator import add, mul, sub, truediv

ops = [add, mul, sub, truediv]


def judgePoint24(nums) -> bool:
    if not nums:
        return False
    n = len(nums)
    if n == 1:
        return round(nums[0], 3) == 24
    for i, j in permutations(range(n), 2):
        # 选2个数字
        x, y = nums[i], nums[j]
        newNums = []
        # 选择加减乘除 4 种运算操作之一,用得到的结果取代选出的 2 个数字
        for k, z in enumerate(nums):
            if k != i and k != j:
                newNums.append(z)
        for k in range(4):
            if k < 2 and i > j:
                # 加法和乘法满足交换律,跳过第二种顺序
                continue
            if k == 3 and round(y, 3) == 0:
                # 除法运算除数不能为0
                continue
            newNums.append(ops[k](x, y))
            if judgePoint24(newNums):
                return True
            newNums.pop()
    return False

然后我们遍历所有的组合进行判断:

from scipy.special import comb

​​​​​​​total = int(comb(9, 4, repetition=True))
cnt = sum(judgePoint24(nums)
          for nums in combinations_with_replacement(range(1, 10), 4))
print(f'{cnt}/{total}={cnt/total:.2%}')

最终一秒内计算出结果:

生成表达式

下面我们加大难度,要求在求解时,能够同时返回可行的表达式。暴力遍历固然可以实现,但是耗时太长,能否在这种回溯算法的基础上实现呢?

我的思路是加个变量记录每次的选择,最终再通过一定的技巧进行还原,最终编码:

from operator import add, mul, sub, truediv
from itertools import permutations, combinations_with_replacement
from collections import defaultdict


def judgePoint24(nums) -> bool:
    ops = [add, mul, sub, truediv]
    op_char = "+*-/"
    record = []

    def solve(nums) -> bool:
        if not nums:
            return False
        n = len(nums)
        if n == 1:
            return round(nums[0], 3) == 24
        for i, j in permutations(range(n), 2):
            # 选2个数字
            x, y = nums[i], nums[j]
            newNums = []
            # 选择加减乘除 4 种运算操作之一,用得到的结果取代选出的 2 个数字
            # 先添加未选择的数字
            newNums = [z for k, z in enumerate(nums) if k not in (i, j)]
            for k in range(4):
                if k < 2 and i > j:
                    # 加法和乘法满足交换律,跳过第二种顺序
                    continue
                if k == 3 and (round(y, 3) == 0):
                    # 除法运算除数不能为0
                    continue
                v = ops[k](x, y)
                newNums.append(v)
                record.append(([round(x, 3), round(y, 3)],
                              op_char[k], round(v, 3)))
                if solve(newNums):
                    return True
                newNums.pop()
                record.pop()
        return False
    flag = solve(nums)
    if not flag:
        return False, ""
    cache = defaultdict(list)
    for ns, op, v in record:
        for i in range(2):
            if cache[ns[i]]:
                ns[i] = "("+cache[ns[i]].pop()+")"
        a, b = ns
        cache[v].append(f"{a}{op}{b}")
    return flag, cache[24][0]+"=24"

然后开始遍历:

total = cnt = 0
for nums in combinations_with_replacement(range(1, 10), 4):
    total += 1
    r, expression = judgePoint24(nums)
    if r:
        print(expression, end="\t")
        cnt += 1
        if cnt % 8 == 0:
            print()
print()
print(f'{cnt}/{total}={cnt/total:.2%}')

最终结果:

可以看到,我们已经得到了404个24点的有效解表达式。

到此这篇关于Python实现快速计算24点游戏的示例代码的文章就介绍到这了,更多相关Python计算24点游戏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • PythonWeb项目Django部署在Ubuntu18.04腾讯云主机上

    PythonWeb项目Django部署在Ubuntu18.04腾讯云主机上

    这篇文章主要介绍了PythonWeb项目Django部署在Ubuntu18.04腾讯云主机上的相关知识,本文通过代码加文字说明的形式给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-04-04
  • 深入理解Python 代码优化详解

    深入理解Python 代码优化详解

    本文初步探讨了 python 常见的性能优化技巧以及如何借助工具来定位和分析程序的性能瓶颈,并提供了相关可以进行性能优化的工具或语言,希望能够更相关人员一些参考。
    2014-10-10
  • Django在pycharm下修改默认启动端口的方法

    Django在pycharm下修改默认启动端口的方法

    今天小编就为大家分享一篇Django在pycharm下修改默认启动端口的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07
  • django自带的权限管理Permission用法说明

    django自带的权限管理Permission用法说明

    这篇文章主要介绍了django自带的权限管理Permission用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • pandas如何使用列表和字典创建 Series

    pandas如何使用列表和字典创建 Series

    这篇文章主要介绍了pandas如何使用列表和字典创建 Series,pandas 是基于NumPy的一种工具,该工具是为解决数据分析任务而创建的,下文我们就来看看文章是怎样介绍pandas,需要的朋友也可以参考一下
    2021-12-12
  • python实现中文文本分句的例子

    python实现中文文本分句的例子

    今天小编就为大家分享一篇python实现中文文本分句的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07
  • Python入门教程(三十五)Python中文件的打开

    Python入门教程(三十五)Python中文件的打开

    这篇文章主要介绍了Python入门教程(三十五)Python中文件的打开,在Python中文件的读取主要是用open()函数,那么open()函数有哪些方法呢,今天我们就来看一看,需要的朋友可以参考下
    2023-05-05
  • Python三百行代码实现飞机大战

    Python三百行代码实现飞机大战

    飞机大战想必大家可能玩过微信的这款小游戏,给我的感觉是这款游戏怎么可以做得这么好呢,操作简单,容易上手,简直是“老少皆宜”啊,既然这款游戏这么棒,能否自己动手用 Python 来实现呢?事实证明是可以的
    2022-09-09
  • 利用Python实现每日新闻推送

    利用Python实现每日新闻推送

    这篇文章主要为大家详细介绍了如何使用Python编写简单的逻辑,通过调用API接口实现每日新闻推送功能,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-06-06
  • python实现对doc,txt,xls文档的读写操作

    python实现对doc,txt,xls文档的读写操作

    这篇文章主要介绍了python实现对doc,txt,xls文档的读写操作,正如标题所见,文章包括三个部分python实现对doc文档的读取、python实现对txt文档的读取和python实现对xls表格的读取,需要的朋友可以参考一下
    2022-04-04

最新评论