24点游戏

2024/1/26 JavaScriptAlgorithm

任意取四个数,用加、减、乘、除(可加括号)运算,使得最终计算结果为24。

/**
 * @description 用四个数凑出24点
 * @author fengchunqi
 * @date 2024-01-23 16:23:34
 * @param {number[]} params
 * @returns {string[]}
 */
function calc24(...params) {
  params = params.slice(0, 4).sort((a, b) => a - b);
  const res = [];
  const operator = ['+', '-', '*', '/'];
  const visited = new Set();
  const calc = (expression) => {
    const len = expression.length;
    const expStr = expression.slice(0).sort().toString();
    if (!visited.has(expStr)) {
      visited.add(expStr);
      if (len > 1) {
        for (let i = 0; i < len - 1; i++) {
          for (let j = i + 1; j < len; j++) {
            const copyExp = expression.slice(0);
            // 选出两个表达式进行计算
            const exp1 = copyExp.splice(j, 1)[0];
            const exp2 = copyExp.splice(i, 1)[0];
            for (let n = 0; n < 4; n++) {
              const newExp = copyExp.slice(0);
              const newExp1 = `${exp1}${operator[n]}${exp2}`;
              const newExp2 = `${exp2}${operator[n]}${exp1}`;
              // 乘法、除法、只有2个表达式时都不需要括号提升优先级
              const noGrouping = n > 1 || len === 2;
              newExp.splice(0, 0, noGrouping ? newExp1 : `(${newExp1})`);
              calc(newExp);
              // 两个表达式不同且不是加法或乘法(加法乘法满足交换律)
              if (exp1 !== exp2 && n % 2) {
                newExp.splice(0, 1, noGrouping ? newExp2 : `(${newExp2})`);
                calc(newExp);
              }
            }
          }
        }
      } else if (Math.abs(eval(expression[0]) - 24) < 1e-6) {
        res.push(expression[0]);
      }
    }
  };
  calc(params);
  return res.length === 0 ? '无法组合出24点' : res;
}
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
console.log({
  '3, 3, 7, 7': calc24(3, 3, 7, 7),
  '3, 3, 8, 8': calc24(3, 3, 8, 8),
  '1, 3, 7, 8': calc24(1, 3, 7, 8),
  '1, 3, 4, 6': calc24(1, 3, 4, 6),
  '2, 4, 10, 10': calc24(2, 4, 10, 10),
  '1, 5, 5, 5': calc24(1, 5, 5, 5),
  '1, 2, 7, 7': calc24(1, 2, 7, 7),
  '4, 7, 8, 8': calc24(4, 7, 8, 8),
  '5, 7, 10, 10': calc24(5, 7, 10, 10),
  '3, 8, 8, 10': calc24(3, 8, 8, 10),
  '1, 3, 3, 4': calc24(1, 3, 3, 4),
  '1, 3, 4, 4': calc24(1, 3, 4, 4),
  '5, 6, 6, 7': calc24(5, 6, 6, 7),
  '6, 10, 10, 10': calc24(6, 10, 10, 10),
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
最近更新: 2024年01月26日 11:05:49