Python实现24点游戏:全排列与表达式生成详解

山间有风
山间有风
发布时间:2026-10-11| 5人浏览过
原创

本文详解如何使用Python实现24点游戏。通过itertools模块进行数字全排列与运算符组合,利用zip_longest和chain拼接表达式,并结合eval与math.isclose处理浮点精度。文章涵盖基础排列、运算符组合及括号优先级处理,提供完整代码逻辑与测试案例。

24点游戏核心逻辑

24点游戏的规则是给定四个0到9之间的数字,通过加减乘除四则运算得出结果24。实现这一目标的核心思路是对这四个数字进行全排列,并在数字之间插入三个运算符,遍历所有可能的操作符组合,最终拼接成完整的数学表达式进行计算。

环境准备与依赖模块

演示环境为Windows 10,使用Python 3.7版本及pycharm 2018.2编辑器。实现过程主要依赖以下标准库模块:

  • math:用于处理浮点数精度判断。
  • itertools:提供全排列和笛卡尔积生成器。
  • collections.abc:用于处理迭代器相关操作。

数字全排列实现

首先,我们需要生成四个数字的所有排列顺序。Python的itertools.permutations函数可以接收一个可迭代对象,并返回其全排列的生成器。若指定第二个参数,则控制选取的数量;若不传,则默认取序列长度。

from itertools import permutations

data_list = permutations([1,2,3,4],2)
for data in data_list:
    print(data)

上述代码的输出结果展示了从[1, 2, 3, 4]中选取2个数字的所有排列情况:

(1, 2)
(1, 3)
(1, 4)
(2, 1)
(2, 3)
(2, 4)
(3, 1)
(3, 2)
(3, 4)
(4, 1)
(4, 2)
(4, 3)

封装获取全排列的函数如下:

def get_all_data_sequence(data_iter):
    return permutations(data_iter)

运算符组合与表达式拼接

在确定数字顺序后,需要在数字之间插入运算符。加减乘除四种运算符(['+', '-', '*', '/'])在四个数字间需要插入三个。我们可以使用itertools.product来获取运算符的笛卡尔积。

product函数返回一个生成器,通过repeat参数指定序列重复的次数。例如,获取三个运算符的所有组合:

from itertools import product

sequence1 = product('ABCD','xy')
sequence2 = product([0,1],repeat=3)

for sequence in sequence1:
    print(sequence)

print('-'*30)

for sequence in sequence2:
    print(sequence)

输出结果展示了不同参数下的笛卡尔积:

('A','x')
('A','y')
('B','x')
('B','y')
('C','x')
('C','y')
('D','x')
('D','y')
------------------------------
(0, 0, 0)
(0, 0, 1)
(0, 1, 0)
(0, 1, 1)
(1, 0, 0)
(1, 0, 1)
(1, 1, 0)
(1, 1, 1)

封装获取运算符序列的函数:

def get_all_operations_sequence():
    operations = ['+','-','*','/']
    return product(operations,repeat=3)

接下来,将数字序列与运算符序列进行拼接。使用zip_longest以最长序列为基准进行配对,缺失值使用fillvalue参数填充(此处为空字符串)。随后,利用chain.from_iterable将嵌套的元组展平为单个迭代器,依次取出值进行字符串拼接。

data = zip_longest([1,2,3,4],['*','-','+'],fillvalue='')
for value in data:
    print(value)

拼接前的元组形式:

(1, '*')
(2, '-')
(3, '+')
(4, '')

展平后的迭代处理:

data = zip_longest([1,2,3,4],['*','-','+'],fillvalue='')
data_chain = chain.from_iterable(data)
for value in data_chain: 
    print(value)

展平后的输出:

1
*
2
-
3
+
4

核心计算逻辑与浮点处理

在遍历所有数字排列和运算符组合后,我们需要构建表达式并计算结果。使用eval函数将拼接好的字符串作为代码执行,返回计算结果。由于浮点数运算存在精度问题,直接使用==判断是否等于24可能不准确,因此引入math.isclose进行近似相等判断。

此外,需处理除数为零的情况,通过try-except块捕获ZeroDivisionError并跳过该次循环。

def calculate(self):
    '''
    计算值,返回对应的表达式和值
    :return: 
    ''' 
    for data_sequence in get_all_data_sequence():  
        operation_sequences = get_all_operation_sequence()  
        for operation_sequence in operation_sequences:   
            value = zip_longest(data_sequence, operation_sequence, 
            fillvalue='')   
            value_chain = chain.from_iterable(value)   
            calculate_str = ''   
            # 对得到的字符进行拼接成为表达式 calculate_str
            for _ in value_chain:    
                calculate_str += _   
            try:
                result = eval(calculate_str)
            # 处理被除数可能为零的情况,然后就直接跳过这次循环
            except ZeroDivisionError:
                continue
            if math.isclose(result, 24):     
                return calculate_str,result
    return None,None

括号优先级的处理

上述基础逻辑仅能处理无括号的线性表达式。然而,24点游戏中括号可以改变运算优先级,例如8/(3-8/3)即可得出24。四个数字的运算中,括号最多有三个。我们需要罗列所有可能的括号组合情况,共计11种模式:

FORM_STRS = [
    # 数字 运算符 数字 运算符 数字 运算符 数字
    # 一个括号 的情况
    '(%s %s %s) %s %s %s %s',
    '(%s %s %s %s %s) %s %s',
    '(%s %s %s %s %s %s %s)',
    '%s %s (%s %s %s) %s %s',
    '%s %s (%s %s %s %s %s)',
    '%s %s %s %s (%s %s %s)',
    # 两个括号 的情况
    '(%s %s %s) %s (%s %s %s)',
    '( (%s %s %s) %s %s) %s %s',
    '( %s %s (%s %s %s)) %s %s',
    '%s %s ((%s %s %s) %s %s)',
    '%s %s (%s %s (%s %s %s))',
    # 三个括号是重复的,就不用罗列出来了
]

在实际实现中,需遍历这11种格式,将数字和运算符填入对应位置,生成带括号的表达式字符串,再次使用eval计算并判断结果。若找到结果为24的表达式,则返回该表达式及结果;若遍历完所有组合仍未找到,则返回None。

测试案例与结果验证

通过上述逻辑,我们可以验证不同的数字组合:

  • 测试1, 2, 3, 4:系统可快速找到1*2*3*4等解法。
  • 测试8, 8, 3, 3:直接线性运算无法得到24,但通过括号组合8/(3-8/3)即可成功运算出24。

该实现方式全面覆盖了数字排列、运算符组合及括号优先级,能够高效解决24点游戏问题。

以上就是Python秒算24点实现及原理详解的详细内容,更多关于Python算法与itertools应用资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。