用python写24点游戏

思路

  1. 通过暴力方法破解(即全排列)
  2. 利用后缀表达式来去除括号的麻烦
  3. 对零这个特殊数字的处理
  4. 再后缀转中缀表达式
# 输入4个[1~13]之间的数字
def Input():
    while True:
        try:
            a, b, c, d = map(int, input("请输入[1~13]之间的四个数字(空格分开):").split())
            for i in [a, b, c, d]:
                if i<1 or i>13:
                    raise ValueError("所输入的数字必须在[1~13]之间")
            break
        except Exception as result:
            print("引发异常:", result)
    return [a, b, c, d]

# 寻找所有符号的排列组合,所得结果是一个常量列表
def Queue_list(li_str):
    queue = ['+', '-', '*', '/']
    ans = []
    while queue:
        string = queue.pop(0)
        if len(string)==3:
            ans.append(string)
            continue
        for i in li_str:
            queue.append(string+i)
    return ans

# 利用回溯寻找出所有数字的排列组合
fuhao = Queue_list(['+', '-', '*', '/'])
def huisu(num, li, result):
    if len(li)==4:
        global fuhao
        for each in fuhao:
            for ans in func(li, each):
                ans = check(ans)
                result.append(ans)
#                 print("答案是:", ans)
    for i in range(len(num)):
        n = num.pop(i)
        huisu(num, li+[n], result)
        num.insert(i, n)
    return result
# 对数字和符号进行排列组合,只用5种排列组合,直接列举
def collect(n, f):
    ans = []
    ans.append([n[0], n[1], f[0], n[2], f[1], n[3], f[2]])
    ans.append([n[0], n[1], f[0], n[2], n[3], f[1], f[2]])
    ans.append(n[0:3]+list(f[0:2])+[n[3]]+[f[2]])
    ans.append(n[0:3]+[f[0]]+[n[3]]+list(f[1:]))
    ans.append(n+list(f))
    return ans

def func(nums, fuhao):
    res = []
    li_all = collect(nums, fuhao)
    for each in li_all:
        ans = kernel(each)
        if -1<(24-ans)*1000<1:
            res.append(each)
    return res

# 核心代码
def kernel(li):
    stack = []
    for i in li:
        if type(i)==type('string'):
            b = stack.pop()
            a = stack.pop()
            if i=='+':
                stack.append(a+b)
            elif i=='-':
                stack.append(a-b)
            elif i=='*':
                stack.append(a*b)
            else:
                if b==0:
                    return 0
                stack.append(a/b)
        else:
            stack.append(i)
    return stack[0]
# 后缀转中缀
def check(li):
    stack = []
    for i in li:
        if type(i)==type('string') and len(i)==1:
            b = str(stack.pop())
            a = str(stack.pop())
            temp = f'({a}{i}{b})'
            stack.append(temp)
        else:
            stack.append(i)
    return stack[0][1:-1]

def main():
    num = Input()
    result = huisu(num, [], [])
    for ans in list(set(result)):
        print("答案是:", ans)

main()

在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是强筱华哇!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值