吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1296|回复: 23
上一主题 下一主题
收起左侧

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

[复制链接]
跳转到指定楼层
楼主
矢岛舞美 发表于 2024-9-24 18:06 回帖奖励
本帖最后由 矢岛舞美 于 2024-9-25 11:16 编辑

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) < 1e-6:
                            return expr
                    except ZeroDivisionError:
                        continue

    return "没有找到能计算出24的方式"


def main():
    while True:
        try:
            # 提示用户输入4个不同的数字
            input_str = input("请输入1-10中的4个不同数字,用空格分隔: ")
            numbers = list(map(int, input_str.split()))

            # 检查输入的数字是否符合要求
            if len(numbers) != 4 or any(n < 1 or n > 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) < 1e-6:
                            return expr
                    except ZeroDivisionError:
                        continue

    return "没有找到能计算出24的方式"


def main():
    while True:
        try:
            # 提示用户输入4个不同的数字
            input_str = input("请输入1-10中的4个不同数字,用空格分隔: ")
            numbers = list(map(int, input_str.split()))

            # 检查输入的数字是否符合要求
            if len(numbers) != 4 or any(n < 1 or n > 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()


增加可视化窗口计算版本:

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) < 1e-6:
                            return expr
                    except ZeroDivisionError:
                        continue

    return "没有找到能计算出24的方式"


def calculate(event=None):
    try:
        # 获取输入的数字
        input_str = entry.get()
        numbers = list(map(int, input_str.split()))

        # 检查输入的数字是否符合要求
        if len(numbers) != 4 or any(n < 1 or n > 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("<Return>", 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()

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
jcning2024 发表于 2024-9-26 09:03
代码中“for ops_permutation in itertools.product(ops, repeat=3)”完全可以去掉,另外和小伙伴玩24,是允许抽出相同数字的,建议“if len(numbers) != 4 or any(n < 1 or n > 10 for n in numbers) or len(set(numbers)) != 4:”去掉len(set(numbers))判断
推荐
qwake 发表于 2024-10-7 12:02
楼主这个效率不高,最佳算法应该是取两个数先进行四则运算,然后将结果与剩下的两个数在进行四则运算,再继续递归,其过程还可以优化
沙发
ABCDWWWc123 发表于 2024-9-24 18:24
3#
darkf 发表于 2024-9-24 18:26
ABCDWWWc123 发表于 2024-9-24 18:24
不错,感谢楼主分享的代码

中学时用扑克牌算的不亦乐乎
4#
010xml 发表于 2024-9-24 18:56
推而广之,可以用于在自然数n中任取4个数算24点吧
5#
rjyq168 发表于 2024-9-24 19:03
代码怎么用?
6#
xingdh 发表于 2024-9-24 20:59
测试了一下,建议添加能输入相同数字的,毕竟24点游戏是允许出现4个6这种的
7#
Link_Stark 发表于 2024-9-24 21:02
小时候跟老爸玩的,计算24点
8#
jjyywg 发表于 2024-9-24 21:07
感谢楼主分享的代码
9#
zlqhysy 发表于 2024-9-24 21:17
编程真需要有聪明的大脑
10#
zk1126853389 发表于 2024-9-25 08:03
感谢楼主分享的代码
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-1 09:19

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表