使用Python脚本枚举24点答案,去除冗余括号,效率没有Ruby版本的好,可能因精度的关系,和其它人些的答案数目不一致,记录之。
# -*- coding:gbk -*-
import itertools as itt
import re
nums = [7, 6, 4, 8]
ops = ['+', '-', '*', '/']
levels = [0, 1, 2]
def simplest(exprstr):
patterns = [re.compile(r"\((\(.+)\)(.+)")\
,re.compile(r"\((.+\))\)(.+)")\
,re.compile(r"(.+)\((\(.+)\)")\
,re.compile(r"(.+)\((.+\))\)")\
,re.compile(r"(.+)\(([^\)]+)\)(.+)")\
,re.compile(r"\((.+)\)(.+\(.+\))")\
,re.compile(r"(\(.+\).+)\((.+)\)")]
rl = [exprstr,exprstr.replace("(","").replace(")","")]
for p in patterns:
m = p.match(exprstr)
if m is not None:
rl.append("".join(m.groups()))
rl.sort(key = len)
for r in rl:
if abs(eval(r) - 24.0) < 1e-10:
return r
def fmtexpr(operand, operators, priority):
i = [i for i, x in enumerate(priority) if x == max(priority)].pop(0)
operand[i] = "({}{}{})".format(operand[i],operators.pop(i),operand.pop(i + 1))
priority.pop(i)
return operand.pop(0) if len(priority) == 0 else fmtexpr(operand,operators,priority)
def check24p(num, op, level):
numfloat = [float(n) for n in num]
return fmtexpr(numfloat, op, level)
answer = set([])
ai = 0
for num in itt.permutations(nums, r = 4):
for op in itt.product(ops, repeat = 3):
for level in itt.permutations(levels, r = len(levels)):
exprstr = check24p(list(num), list(op), list(level))
try:
if abs(eval(exprstr) - 24.0) < 1e-10:
ai = ai + 1
exprstr = simplest(exprstr[1:-1])
answer.add(exprstr.replace(".0",""))
except ZeroDivisionError:
continue
print("共{}种解法,化简后剩余{}种解法:".format(ai, len(answer)))
for a in answer:
print("我答24点 " + a)