24点

24点简介

24点游戏是对4个数字进行加、减、乘、除四则运算(可以加括号),使计算结果等于24的小游戏。这4个数字从一副抽去大小王的扑克牌抽取,数字范围是1~13,其中J、Q、K分别代表11、12、13。

算法

  1. 输入4个数字作为24点的题目
  2. 生成数字列表与运算符列表
  3. 生成表达式的所有括号组合
    用a,b,c,d代表数字,op1,op2,op3代表运算符,括号组合包括以下5种:
1
2
3
4
5
((a op1 b) op2 c) op3 d,
(a op1 (b op2 c)) op3 d,
(a op1 b) op2 (c op3 d),
a op1 ((b op2 c) op3 d),
a op1 (b op2 (c op3 d))
  1. 验证表达式是否等于24,注意浮点数精度问题和除以零报错
  2. 输出解法

Python解题代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import itertools


def generate_expressions(numbers, operators):
"""生成表达式的所有括号组合"""
a, b, c, d = numbers
op1, op2, op3 = operators

expressions = [
f"(({a}{op1}{b}){op2}{c}){op3}{d}",
f"({a}{op1}({b}{op2}{c})){op3}{d}",
f"({a}{op1}{b}){op2}({c}{op3}{d})",
f"{a}{op1}(({b}{op2}{c}){op3}{d})",
f"{a}{op1}({b}{op2}({c}{op3}{d}))",
]

return expressions


def is_solution(expr):
"""验证表达式是否等于24"""
try:
return abs(eval(expr) - 24) < 1e-6
except ZeroDivisionError:
return False


def solve(numbers):
"""解决24点问题的主函数"""
# 生成去重后的数字列表
number_list = list(set(itertools.permutations(numbers)))

# 生成运算符列表
operators = ["+", "-", "*", "/"]
operator_list = list(itertools.product(operators, repeat=3))

solutions = []

for nums in number_list:
for ops in operator_list:
# 生成表达式的所有括号组合
expressions = generate_expressions(nums, ops)

# 验证表达式是否等于24
for expr in expressions:
if is_solution(expr):
solutions.append(expr)

# 输出所有解法
if not solutions:
print("没有找到解法")
else:
print("找到以下解法:")
print('\n'.join(solutions))


if __name__ == "__main__":
numbers = [2, 3, 5, 12]
solve(numbers)