为什么会记录这道题,是因为前同事让解下,虽然都知道怎么解,但是实际没去写过,所以就顺手记录下。
这里不考虑对等表达式的问题,只是列出全部解,除了递归组合求解(不降维),还有另一种方法是递归降维组合求解。本质上区别不大,有兴趣的可以自己尝试下。
所谓的降维是指将四个数两两组合成一个数,直到只剩最终结果:4 -> 3 -> 2 -> 1
代码只用到了内置库(算法题的考查一般只允许使用内置库及内置函数,不允许使用第三方库),节省一些不必要的代码步骤,计算及判断使用内置的eval来快速求解,求解代码并不属于核心代码,本质上只要能列出表达式,基本这道题的考查就结束了。不使用eval无非就是自己再封装下计算步骤的函数而已。
# -*- coding: utf-8 -*-
from itertools import permutations
OS = ['+', '-', '*', '/'] * 3
全排列运算符号 = list(permutations(OS, 3))
表达式组合 = [
# 无括号
"{x[0]} {os[0]} {x[1]} {os[1]} {x[2]} {os[2]} {x[3]}",
# 单对括号
"({x[0]} {os[0]} {x[1]}) {os[1]} {x[2]} {os[2]} {x[3]}",
"{x[0]} {os[0]} ({x[1]} {os[1]} {x[2]}) {os[2]} {x[3]}",
"{x[0]} {os[0]} {x[1]} {os[1]} ({x[2]} {os[2]} {x[3]})",
# 双对括号(未嵌套)
"({x[0]} {os[0]} {x[1]}) {os[1]} ({x[2]} {os[2]} {x[3]})",
# 双对括号(嵌套)
"(({x[0]} {os[0]} {x[1]}) {os[1]} {x[2]}) {os[2]} {x[3]}",
"({x[0]} {os[0]} ({x[1]} {os[1]} {x[2]})) {os[2]} {x[3]}",
"{x[0]} {os[0]} (({x[1]} {os[1]} {x[2]}) {os[2]} {x[3]})",
"{x[0]} {os[0]} ({x[1]} {os[1]} ({x[2]} {os[2]} {x[3]}))"
]
def Point24Evo(arr: list) -> set and bool:
全排列数组 = list(permutations(arr, 4))
ok, solutions = False, set()
for x in 全排列数组:
for e in 表达式组合:
for os in 全排列运算符号:
es = e.format(x=x, os=os)
try:
ok = eval(f"{es} == 24") or eval(f"{es} == 24.0")
except ZeroDivisionError:
ok = False
continue
if ok: # 有解
solutions.add(es)
pass
pass
if len(solutions) != 0:
return solutions, True
else:
return solutions, False
if __name__ == "__main__":
solutions, ok = Point24Evo([4, 2, 2, 1])
if ok:
[print(es) for es in sorted(list(solutions))]
else:
print("无解")
pass