Python计算24点

本文介绍了一种使用Python实现的四则运算求24点的方法,通过递归生成所有可能的运算组合,并利用数学函数判断结果是否接近24。代码实现了节点类构造表达式树,以及遍历所有数的排列组合。
import math
import itertools

class Node(object):
    def __init__(self, result=None):
        self._left = None
        self._right = None
        self._operator = None
        self._result = result

    def set_expression(self, left_node, right_node, operator):
        self._left = left_node
        self._right = right_node
        self._operator = operator
        expression = "{} {} {}".format(left_node._result, operator, right_node._result)
        self._result = eval(expression)                        #将字符串str当成有效的表达式来求值并返回计算结果

    def __repr__(self):                                        # 重写repr方法
        if self._operator:
            return '<Node operator="{}">'.format(self._operator)
        else:
            return '<Node value="{}">'.format(self._result)

def get_expression(tree):
    if tree._operator == None:
        return str(tree._result)
    left_expression = get_expression(tree._left)
    right_expression = get_expression(tree._right)
    expression = "({} {} {})".format(left_expression, tree._operator, right_expression)
    return expression

def build_tree(left_tree, right_tree):
    treelist = []
    tree1 = Node()
    tree1.set_expression(left_tree, right_tree, "+")
    treelist.append(tree1)
    tree2 = Node()
    tree2.set_expression(left_tree, right_tree, "-")
    treelist.append(tree2)
    tree4 = Node()
    tree4.set_expression(left_tree, right_tree, "*")
    treelist.append(tree4)
    if right_tree._result != 0:
        tree5 = Node()
        tree5.set_expression(left_tree, right_tree, "/")
        treelist.append(tree5)
    return treelist

def build_all_trees(array):
    if len(array) == 1:
        tree = Node(array[0])
        return [tree]

    treelist = []
    for i in range(1, len(array)):
        left_array = array[:i]
        right_array = array[i:]
        left_trees = build_all_trees(left_array)
        right_trees = build_all_trees(right_array)
        for left_tree in left_trees:
            for right_tree in right_trees:
                combined_trees = build_tree(left_tree, right_tree)
                treelist.extend(combined_trees)                     # list.extend() 用新列表扩展原来的列表
    return treelist                                                 # 返回值treelist为两个子树四则远算的所有结果的列表

if __name__ == "__main__":
    questions = [
        [7,7,3,3],
        [8,3,8,3],
        [5,1,5,5],
        [10,10,4,4],
        [1,5,7,10],
        [4,7,8,10],
        [2,2,3,10],
        [2,4,10,10],
        [9,10,6,9],
        [4,4,7,7],
        [1,4,5,6],
        [2,5,5,10]
    ]

    for question in questions:
        perms = itertools.permutations(question)                    #找到四个数字的全排列,返回值为一个迭代器
        found = False
        for perm in perms:
            treelist = build_all_trees(perm)
            for tree in treelist:
                if math.isclose(tree._result, 24, rel_tol=1e-10):
                    expression = get_expression(tree)
                    print(expression)
                    found = True
                    break
            if found:
                break

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值