【JavaScript】计算24点

华为算法题1: 

/**
 * 计算24点是一种扑克牌益智游戏,随机抽出4张扑克牌,通过加(+),减(-),乘(*), 除(/)四种运算法则计算得到整数24,本问题中,扑克牌通过如下字符或者字符串表示,其中,小写joker表示小王,大写JOKER表示大王: 
 * 3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
 * 本程序要求实现:输入4张牌,输出一个算式,算式的结果为24点。 
 * 详细说明: 
 * 1.运算只考虑加减乘除运算,没有阶乘等特殊运算符号,友情提醒,整数除法要当心; 
 * 2.牌面2~10对应的权值为2~10, J、Q、K、A权值分别为为11、12、13、1; 
 * 3.输入4张牌为字符串形式,以一个空格隔开,首尾无空格;如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算; 
 * 4.输出的算式格式为4张牌通过+-*\/四个运算符相连,中间无空格,4张牌出现顺序任意,只要结果正确; 
 * 5.输出算式的运算顺序从左至右,不包含括号,如1+2+3*4的结果为24
 * 6.如果存在多种算式都能计算得出24,只需输出一种即可,如果无法得出24,则输出“NONE”表示无解。
 */

let arr = [];
+function(){
    Array.prototype.remove = function(val) {
        let index = this.indexOf(val);
        if(index > -1) {
            this.splice(index, 1);
        }
    }
    // 输入四张牌
    let n1 = '4 2 K A';
    let list = n1.split(' ');
    // 四张牌转换数字
    list = trans(list);
    // 做4次拆解,每次将最后一位数字放到第一位
    d('', list);
    for(let i=0; i< list.length-1; i++) {
        d('', turn(list));
    }
    if(arr.length == 0) {
        print('NONE');
    }else {
        print(arr[0]);
    }
}();

function trans(list) {
    // 转化牌面 转为数字
    return list.map(val => {
        if(val == 'J') {
            return 11;
        }else if(val == 'Q') {
            return 12;
        }else if(val == 'K') {
            return 13;
        }else if(val == 'A') {
            return 1;
        }else {
            return Number(val);
        }
    });
}

// 将数组最后一位数字放到第一位
function turn(list) {
    list.unshift(list[list.length-1]);
    list.splice(-1);
    return list;
}

// 计算
function d(str, list_) {
    let can = false;
    // 浅拷贝数组
    let list = [...list_];
    // 锁住数组第一个参数
    let a = list[0];
    // 其余数字做新数组遍历
    list.remove(a);
    if(list.length > 2) {
        // 当数组超过2个,做递归
        d(`${str} ${a}`, list);
        for(let i=0; i< list.length-1; i++) {
            d(`${str} ${a}`, turn(list));
        }
    }
    else {
        // 当数组减少到只剩2个数字,开始排列
        // 将之前截取的数字拼起来
        let l1 = `${str} ${a}`.trim().split(' ');
        let l2 = [...l1];
        // 排列1
        l1.push(list[0]);
        l1.push(list[1]);
        can = y1(l1);
        if(!can) {
            // 排列2
            l2.push(list[1]);
            l2.push(list[0]);
            can = y1(l2);
        }
    }
    return can;
}

function y1(list) {
    // 四张牌运算
    // 运算法则
    let soul = ['+', '-', '*', '/'];
    let a = list[0];
    let b = list[1];
    let c = list[2];
    let d = list[3];
    let can = false;
    // 锁住第一个数字位置
    for(let i=0; i< 4 && !can; i++) {
        // 锁住第二个数字位置
        for(let j=0; j< 4 && !can; j++) {
            // 锁住第三个数字位置
            for(let k=0; k< 4 && !can; k++) {
                // 穷举处理括号
                let s = `${a}${soul[i]}${b}${soul[j]}${c}${soul[k]}${d}`;
                let s1 = '', s2 = '', s3 = '';
                if(i == 0 || i == 1) {
                    if(j ==0 || j == 1) {
                        if(k == 0 || k == 1) {
                        }else {
                            s1 = `(${a}${soul[i]}${b}${soul[j]}${c})${soul[k]}${d}`;
                        }
                    }else {
                        if(k == 0 || k == 1) {
                            s1 = `(${a}${soul[i]}${b})${soul[j]}${c}${soul[k]}${d}`;
                            s2 = `(${a}${soul[i]}${b})${soul[j]}(${c}${soul[k]}${d})`;
                            s3 = `${a}${soul[i]}${b}${soul[j]}(${c}${soul[k]}${d})`;
                        }else {
                            s1 = `(${a}${soul[i]}${b})${soul[j]}${c}${soul[k]}${d}`;
                        }
                    }
                }else {
                    if(j ==0 || j == 1) {
                        if(k == 0 || k == 1) {
                            s1 = `${a}${soul[i]}(${b}${soul[j]}${c})${soul[k]}${d}`;
                            s2 = `${a}${soul[i]}(${b}${soul[j]}${c}${soul[k]}${d})`;
                        }else {
                            s1 = `(${a}${soul[i]}${b}${soul[j]}${c})${soul[k]}${d}`;
                            s2 = `${a}${soul[i]}(${b}${soul[j]}${c}${soul[k]}${d})`;
                            s3 = `${a}${soul[i]}(${b}${soul[j]}${c})${soul[k]}${d}`;
                        }
                    }else {
                        if(k == 0 || k == 1) {
                            s1 = `${a}${soul[i]}${b}${soul[j]}(${c}${soul[k]}${d})`;
                        }
                    }
                }
                // 计算总和
                let sum = eval(s);
                let sum1 = s1 != ''? eval(s1) : 0;
                let sum2 = s2 != ''? eval(s2) : 0;
                let sum3 = s3 != ''? eval(s3) : 0;
                if(sum == 24) {
                    // print(s);
                    arr.push(s);
                    can = true;
                }
                if(sum1 == 24) {
                    // print(s1);
                    arr.push(s1);
                    can = true;
                }
                if(sum2 == 24) {
                    // print(s2);
                    arr.push(s2);
                    can = true;
                }
                if(sum3 == 24) {
                    // print(s3);
                    arr.push(s3);
                    can = true;
                }
            }
        }
    }
    return can;
}


function print(msg) {
    console.log(msg)
}

使用穷举法,因为边工作边写的,还有细节待完善,Joker这些还没写,准备做一个24点小游戏的Electron

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值