【中等】算法nodeJs:24点游戏算法

0 阅读1分钟

描述

对于给定的四个小于 10 的正整数,你需要计算它们能否通过计算得到数字 24。让我们来回忆标准二十四点游戏的规则:
∙输入的数字可能会重复,每一个数字必须用且只能用一次;
∙运算顺序可以任意安排,且可以使用括号进一步地改变运算优先级;
∙允许使用加、减、乘、除四种算数运算符,其中除法是实数除法;
如果可以得到 24,输出 true,否则,直接输出 false。

输入描述:

在一行上输入四个整数 a,b,c,d(1≦a,b,c,d≦10) 代表等待计算的数字。

输出描述:

如果可以通过规定的计算得到 24,输出 true,否则,直接输出 false。

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
    // Write your code here
    const arr = (await readline()).split(" ").map(Number);
    function canGet24(nums) {
        // 生成全排列函数
        function permute(arr, m = []) {
            if (arr.length === 0) {
                return [m];
            }
            let result = [];
            for (let i = 0; i < arr.length; i++) {
                let curr = arr.slice();
                let next = curr.splice(i, 1);
                result.push(...permute(curr.slice(), m.concat(next)));
            }
            return result;
        }

        // 生成所有可能的运算符组合
        const operators = ["+", "-", "*", "/"];

        // 递归计算函数
        function calculate(nums, ops) {
            if (nums.length === 1) {
                return Math.abs(nums[0] - 24) < 1e-6;
            }

            for (let i = 0; i < nums.length - 1; i++) {
                for (let op of operators) {
                    let newNums = nums.slice();
                    let a = newNums[i],
                        b = newNums[i + 1];

                    let res;
                    switch (op) {
                        case "+":
                            res = a + b;
                            break;
                        case "-":
                            res = a - b;
                            break;
                        case "*":
                            res = a * b;
                            break;
                        case "/":
                            if (b !== 0) {
                                res = a / b;
                            } else {
                                continue;
                            }
                            break;
                    }

                    newNums.splice(i, 2, res);
                    if (calculate(newNums, ops)) {
                        return true;
                    }
                }
            }
            return false;
        }

        // 生成所有可能的数字排列
        let permutations = permute(nums);

        // 尝试每一种排列
        for (let permutation of permutations) {
            if (calculate(permutation, [])) {
                return true;
            }
        }

        return false;
    }
    console.log(canGet24(arr));
})();