算 24 点
问题
算 24 点游戏是一种经典的用扑克牌来进行的益智游戏。游戏内容是:从一副扑克牌中抽去大小王剩下 52 张,任意抽取 4 张牌,把牌面上的数字(J、Q、K、A 分别代表 11、12、13、1)运用加、减、乘、除和括号进行运算得出 24。每张牌都必须使用一次,但不能重复使用。
请编写代码对任意给出的四张牌算 24 点,用文本输出解答,如果无解则输出“无解”。
思路
-
将 4 个数字按照不同的顺序进行排列
-
在 1 的循环中,将 4 个运算符取其中三个并且按照不同的方式进行排列
-
在 2 的循环中,将三个符号添加到四个数字之间
-
枚举了以下 5 种括号情况分别计算(其中 A,B,C,D 表示数字,# 表示不同的符号):
- ((A#B)#C)#D
- (A#(B#C))#D
- (A#B)#(C#D)
- A#((B#C)#D)
- A#(B#(C#D))
代码
A | B | C | D | ||
---|---|---|---|---|---|
1 | [3,3,8,8] | ||||
2 | [1234,1243,1324,1342,1423,1432,2134,2143,2314,2341,2413,2431,3124,3142,3214,3241,3412,3421,4123,4132,4213,4231,4312,4321] | ||||
3 | for A2 | =A1(4.(int(A3/power(10,4-#))%10)) | 将 A1 中的成员按照 A2 排列 | ||
4 | for 64 | 在 +,_,*,/ 四个运算符中取任意 3 个,可以相同,因此每一个都有四种选择,相当于 4×4×4,等于 64 种 | |||
5 | =["+","-","*","/"](3.(int((B4-1)/power(4,3-#))%4+1)) | 把循环序号转成四进制数且每位加 1,即为当前的运算符选法 | |||
6 | >a=B3(1),b=B3(2),c=B3(3),d=B3(4),x=C5(1),y=C5(2),z=C5(3) | ||||
7 | =func(A28,[x,a,func(A28,[y,b,func(A28,[z,c,d])])]) | 给表达式添加括号,该表达式为 A#(B#(C#D)),然后调用子程序进行计算 | |||
8 | if abs(C7-24)<0.0001 | ||||
9 | =string(a)+x+"("+string(b)+y+"("+string(c)+z+string(d)+"))" | ||||
10 | =D10|D9 | 如果表达式的值等于 24,存储结果 | |||
11 | =func(A28,[x,a,func(A28,[z,func(A28,[y,b,c]),d])]) | 给表达式添加括号,该表达式为 A#((B#C)#D),然后调用子程序进行计算 | |||
12 | if abs(C11-24)<0.0001 | ||||
13 | =string(a)+x+"(("+string(b)+y+ string(c)+")"+z+string(d)+")" | ||||
14 | =D14|D13 | 如果表达式的值等于 24,存储结果 | |||
15 | =func(A28,[y,func(A28,[x,a,b]),func(A28,[z,c,d])]) | 给表达式添加括号,该表达式为 (A#B)#(C#D),然后调用子程序进行计算 | |||
16 | if abs(C15-24)<0.0001 | ||||
17 | ="("+string(a)+x+string(b)+")"+y+"("+string(c)+z+string(d)+")" | ||||
18 | =D18|D17 | 如果表达式的值等于 24,存储结果 | |||
19 | =func(A28,[z,func(A28,[y,func(A28,[x,a,b]),c]),d]) | 给表达式添加括号,该表达式为 ((A#B)#C)#D,然后调用子程序进行计算 | |||
20 | if abs(C19-24)<0.0001 | ||||
21 | ="(("+string(a)+x+string(b)+")"+y+string(c)+")"+z+string(d) | ||||
22 | =D22|D21 | 如果表达式的值等于 24,存储结果 | |||
23 | =func(A28,[z,func(A28,[x,a,func(A28,[y,b,c])]),d]) | 给表达式添加括号,该表达式为 (A#(B#C))#D,然后调用子程序进行计算 | |||
24 | if abs(C23-24)<0.0001 | ||||
25 | ="("+string(a)+x+"("+string(b)+y+string(c)+"))"+z+string(d) | ||||
26 | =D26|D25 | 如果表达式的值等于 24,存储结果 | |||
27 | =[D10,D14,D18,D22,D26].union().id() | 运算结果 | |||
28 | func | 三个参数,第一个参数是运算符,第二个参数是左操作数,第三个参数是右操作数 | |||
29 | if A28(1)=="+" | return A28(2)+A28(3) | |||
30 | if A28(1)=="-" | return A28(2)-A28(3) | |||
31 | if A28(1)=="*" | return A28(2)*A28(3) | |||
32 | if A28(1)=="/" | return A28(2)/A28(3) |
英文版