利用二叉树遍历解决24点问题
Source Code
#!/usr/bin/python
# -*- coding: utf-8 -*-
# @Time : 2020/11/12 21:50
# @Author : SandQuant
import itertools
def add(a, b):
return a + b
def sub(a, b):
return a - b
def pro(a, b):
return a * b
def div(a, b):
return a / b
def generate_tree(tree):
root = []
root_leaf = []
deep = max(map(lambda x: x[0], tree))
trees = dict.fromkeys(range(1, deep + 1), [])
for leaf in tree:
trees[leaf[0]] = trees[leaf[0]] + [leaf]
for level in range(1, deep + 1):
for i in range(int(len(trees[deep + 1 - level]) / 2)):
_1 = trees[deep + 1 - level][i * 2]
_2 = trees[deep + 1 - level][i * 2 + 1]
father_root = (_1[0] - 1, int((_1[1] + _2[1] + 1) / 4))
if father_root in trees[deep - level]:
root.append(str(father_root))
root_leaf.append([str(father_root), '{}({},{})'.format(father_root, _1, _2)])
root_leaf.sort()
for i in range(1, len(root_leaf)):
target = root_leaf[0][1]
tool_key = root_leaf[i][0]
tool = root_leaf[i][1]
root_leaf[0][1] = target.replace(tool_key, tool)
leaf = [str(x) for x in tree if str(x) not in root]
root.sort()
leaf.sort()
return root, leaf, root_leaf[0][1]
def solve_24(root, leaf, function, operation, num):
num_combine = list(set(list(itertools.permutations(num, 4))))
ope_combine = list(itertools.product(operation, repeat=3))
for nums in num_combine:
for opes in ope_combine:
equation = function
foot_function = dict(zip(root, list(opes)))
leaf_function = dict(zip(leaf, list(nums)))
replace_rule = dict(foot_function, **leaf_function)
for key in replace_rule.keys():
equation = equation.replace(key, str(replace_rule[key]))
try:
if eval(equation) == 24:
print(equation)
except:
continue
if __name__ == '__main__':
operation = ['add', 'sub', 'pro', 'div']
num = [4, 4, 7, 7]
tree_1 = [(1, 1), (2, 1), (2, 2), (3, 1), (3, 2), (3, 3), (3, 4)]
tree_2 = [(1, 1), (2, 1), (2, 2), (3, 1), (3, 2), (4, 1), (4, 2)]
tree_3 = [(1, 1), (2, 1), (2, 2), (3, 1), (3, 2), (4, 3), (4, 4)]
tree_4 = [(1, 1), (2, 1), (2, 2), (3, 3), (3, 4), (4, 5), (4, 6)]
tree_5 = [(1, 1), (2, 1), (2, 2), (3, 3), (3, 4), (4, 7), (4, 8)]
for tree in [tree_1, tree_2, tree_3, tree_4, tree_5]:
root, leaf, root_leaf = generate_tree(tree)
solve_24(root, leaf, root_leaf, operation, num)
Output
pro(sub(4,div(4,7)),7)
pro(7,sub(4,div(4,7)))
分别代表:
pro(sub(4,div(4,7)),7):(4-(4/7))7=24
pro(7,sub(4,div(4,7))):7(4-(4/7))=24
本质是一样的,但运算顺序不同
欢迎关注~ SandQuant 专注于全球金融数据和量化投资策略