锻炼大脑:使用四则运算计算结果为24的组合方式

查看 85|回复 11
作者:矢岛舞美   
1、2、3、4、5、6、7、8、9、10这10个数字中任取4个不同的数,用加减乘除算出24
210种取法,其中13种无解,197种可以算出24
代码+exe成品:https://www.123865.com/s/TKR5Vv-rwK5v
((1 + 2) + 3) * 4
2 * ((3 + 4) + 5)
((3 - 4) + 5) * 6
4 * ((5 - 6) + 7)
((5 + 7) - 8) * 6
(6 * 8) / (9 - 7)
(8 * 9) / (10 - 7)
[Python] 纯文本查看 复制代码import itertools
import operator
def find_24(nums):
    if len(nums) != 4:
        raise ValueError("必须输入4个数")
    ops = [operator.add, operator.sub, operator.mul, operator.truediv]
    op_symbols = ['+', '-', '*', '/']
    # 尝试所有数字的排列
    for num_permutation in itertools.permutations(nums):
        # 尝试所有运算符的排列
        for ops_permutation in itertools.product(ops, repeat=3):
            # 尝试所有运算符的符号排列
            for op_symbols_permutation in itertools.product(op_symbols, repeat=3):
                # 尝试所有可能的括号位置
                expressions = [
                    f"(({num_permutation[0]} {op_symbols_permutation[0]} {num_permutation[1]}) {op_symbols_permutation[1]} {num_permutation[2]}) {op_symbols_permutation[2]} {num_permutation[3]}",
                    f"({num_permutation[0]} {op_symbols_permutation[0]} ({num_permutation[1]} {op_symbols_permutation[1]} {num_permutation[2]})) {op_symbols_permutation[2]} {num_permutation[3]}",
                    f"({num_permutation[0]} {op_symbols_permutation[0]} {num_permutation[1]}) {op_symbols_permutation[1]} ({num_permutation[2]} {op_symbols_permutation[2]} {num_permutation[3]})",
                    f"{num_permutation[0]} {op_symbols_permutation[0]} (({num_permutation[1]} {op_symbols_permutation[1]} {num_permutation[2]}) {op_symbols_permutation[2]} {num_permutation[3]})",
                    f"{num_permutation[0]} {op_symbols_permutation[0]} ({num_permutation[1]} {op_symbols_permutation[1]} ({num_permutation[2]} {op_symbols_permutation[2]} {num_permutation[3]}))"
                ]
                for expr in expressions:
                    try:
                        if abs(eval(expr) - 24)  10 for n in numbers) or len(set(numbers)) != 4:
                raise ValueError
            # 查找能计算出24的方式
            result = find_24(numbers)
            print(result)
            break
        except ValueError:
            print("输入无效,请输入1-10中的4个不同数字。")
if __name__ == "__main__":
    main()
感觉这样不太方便,优化了两下
添加循环可连续输入版本:
[Python] 纯文本查看 复制代码import itertools
import operator
def find_24(nums):
    if len(nums) != 4:
        raise ValueError("必须输入4个数")
    ops = [operator.add, operator.sub, operator.mul, operator.truediv]
    op_symbols = ['+', '-', '*', '/']
    # 尝试所有数字的排列
    for num_permutation in itertools.permutations(nums):
        # 尝试所有运算符的排列
        for ops_permutation in itertools.product(ops, repeat=3):
            # 尝试所有运算符的符号排列
            for op_symbols_permutation in itertools.product(op_symbols, repeat=3):
                # 尝试所有可能的括号位置
                expressions = [
                    f"(({num_permutation[0]} {op_symbols_permutation[0]} {num_permutation[1]}) {op_symbols_permutation[1]} {num_permutation[2]}) {op_symbols_permutation[2]} {num_permutation[3]}",
                    f"({num_permutation[0]} {op_symbols_permutation[0]} ({num_permutation[1]} {op_symbols_permutation[1]} {num_permutation[2]})) {op_symbols_permutation[2]} {num_permutation[3]}",
                    f"({num_permutation[0]} {op_symbols_permutation[0]} {num_permutation[1]}) {op_symbols_permutation[1]} ({num_permutation[2]} {op_symbols_permutation[2]} {num_permutation[3]})",
                    f"{num_permutation[0]} {op_symbols_permutation[0]} (({num_permutation[1]} {op_symbols_permutation[1]} {num_permutation[2]}) {op_symbols_permutation[2]} {num_permutation[3]})",
                    f"{num_permutation[0]} {op_symbols_permutation[0]} ({num_permutation[1]} {op_symbols_permutation[1]} ({num_permutation[2]} {op_symbols_permutation[2]} {num_permutation[3]}))"
                ]
                for expr in expressions:
                    try:
                        if abs(eval(expr) - 24)  10 for n in numbers) or len(set(numbers)) != 4:
                raise ValueError
            # 查找能计算出24的方式
            result = find_24(numbers)
            print(result)
        except ValueError:
            print("输入无效,请输入1-10中的4个不同数字。")
        # 提示用户是否继续
        continue_input = input("是否继续输入新的数字进行计算?(y/n): ").strip().lower()
        if continue_input != 'y':
            break
if __name__ == "__main__":
    main()
增加可视化窗口计算版本:


QQ截图20240925110216.jpg (20.98 KB, 下载次数: 0)
下载附件
2024-9-25 11:05 上传

[color=]exe成品:https://www.123865.com/s/TKR5Vv-rwK5v
[Python] 纯文本查看 复制代码import itertools
import operator
import tkinter as tk
from tkinter import messagebox
def find_24(nums):
    if len(nums) != 4:
        raise ValueError("必须输入4个数")
    ops = [operator.add, operator.sub, operator.mul, operator.truediv]
    op_symbols = ['+', '-', '*', '/']
    # 尝试所有数字的排列
    for num_permutation in itertools.permutations(nums):
        # 尝试所有运算符的排列
        for ops_permutation in itertools.product(ops, repeat=3):
            # 尝试所有运算符的符号排列
            for op_symbols_permutation in itertools.product(op_symbols, repeat=3):
                # 尝试所有可能的括号位置
                expressions = [
                    f"(({num_permutation[0]} {op_symbols_permutation[0]} {num_permutation[1]}) {op_symbols_permutation[1]} {num_permutation[2]}) {op_symbols_permutation[2]} {num_permutation[3]}",
                    f"({num_permutation[0]} {op_symbols_permutation[0]} ({num_permutation[1]} {op_symbols_permutation[1]} {num_permutation[2]})) {op_symbols_permutation[2]} {num_permutation[3]}",
                    f"({num_permutation[0]} {op_symbols_permutation[0]} {num_permutation[1]}) {op_symbols_permutation[1]} ({num_permutation[2]} {op_symbols_permutation[2]} {num_permutation[3]})",
                    f"{num_permutation[0]} {op_symbols_permutation[0]} (({num_permutation[1]} {op_symbols_permutation[1]} {num_permutation[2]}) {op_symbols_permutation[2]} {num_permutation[3]})",
                    f"{num_permutation[0]} {op_symbols_permutation[0]} ({num_permutation[1]} {op_symbols_permutation[1]} ({num_permutation[2]} {op_symbols_permutation[2]} {num_permutation[3]}))"
                ]
                for expr in expressions:
                    try:
                        if abs(eval(expr) - 24)  10 for n in numbers) or len(set(numbers)) != 4:
            raise ValueError
        # 查找能计算出24的方式
        result = find_24(numbers)
        result_label.config(text=result)
        # 将结果添加到历史记录
        history_listbox.insert(tk.END, f"{input_str} -> {result}")
    except ValueError:
        messagebox.showerror("输入错误", "输入无效,请输入1-10中的4个不同数字。")
# 创建主窗口
root = tk.Tk()
root.title("24点计算器")
# 创建并放置标签、输入框和按钮
instruction_label = tk.Label(root, text="请输入1-10中的4个不同数字,用空格分隔:")
instruction_label.pack()
entry = tk.Entry(root)
entry.pack()
entry.bind("", calculate)  # 绑定 Enter 键到 calculate 函数
calculate_button = tk.Button(root, text="计算", command=calculate)
calculate_button.pack()
result_label = tk.Label(root, text="")
result_label.pack()
# 创建历史记录框
history_label = tk.Label(root, text="历史记录:")
history_label.pack()
history_listbox = tk.Listbox(root, width=50, height=10)
history_listbox.pack()
# 运行主循环
root.mainloop()

数字, 排列

jcning2024   

代码中“for ops_permutation in itertools.product(ops, repeat=3)”完全可以去掉,另外和小伙伴玩24,是允许抽出相同数字的,建议“if len(numbers) != 4 or any(n  10 for n in numbers) or len(set(numbers)) != 4:”去掉len(set(numbers))判断
qwake   

楼主这个效率不高,最佳算法应该是取两个数先进行四则运算,然后将结果与剩下的两个数在进行四则运算,再继续递归,其过程还可以优化
ABCDWWWc123   

不错,感谢楼主分享的代码
darkf   


ABCDWWWc123 发表于 2024-9-24 18:24
不错,感谢楼主分享的代码

中学时用扑克牌算的不亦乐乎
010xml   

推而广之,可以用于在自然数n中任取4个数算24点吧
rjyq168   

代码怎么用?
xingdh   

测试了一下,建议添加能输入相同数字的,毕竟24点游戏是允许出现4个6这种的
Link_Stark   

小时候跟老爸玩的,计算24点
jjyywg   

感谢楼主分享的代码
您需要登录后才可以回帖 登录 | 立即注册

返回顶部