码迷,mamicode.com
首页 > 其他好文 > 详细

计算24

时间:2019-03-02 11:03:21      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:var   sorted   set   必须   数通   数值   fun   []   nod   

快算24是一种挺好的锻炼孩子算数能力的扑克牌游戏,它的游戏方式是把四张牌的牌面数值通过有限四则运算得到结果24,四张牌必须仅用一次。各地玩法还有点差别,有的只算1-10,其它抽出来;有的地方把整幅牌都算上,把其中J当作11,Q当作12,K当作13,小王当作15,大王当作18. 个人觉得后者不但省了理牌的功夫还更能锻炼人。

绝大多数四张牌的组合都容易算出来,有部分就要费点脑筋了,如5,5,5,1;3,7,3,7;12,12,12,10...,当然也有完全算不出来的,如5,7,8,11;1,1,6,11...从规律上讲,似乎5,7,11,13这样的素数参与越多越是难算。

算24也是有窍门的,那就是逐步缩小范围,具体来说是看三个数运算能否和第四个数通过加减乘除得到24,继而看三个数操作能否得到24和第四个数的四则运算结果,继而看两个数的操作能否得到第三个数和上次结果的四则运算结果。具体比如有2,3,4,12四个数,看到12后想2,3,4是否能组合个2出来,然后想到2X3-4的方案,或者2X(4-3)的方案。

按照这个思维我编了下面的程序。具体思路是这样的,先制作一个C4类(2,3,4,12,24),这个类会形成24种组合(以及六种特殊组合方式),再由24种组合生成6种子方案,子方案又生成六种孙方案,最后挑选出符合条件的结果。

代码是这样的:
//======================================================
// 算24 C4 1.02
// 整理代码,去掉一些多余冗杂的地方
// 2018年4月23日 完成
// 2019年3月2日修改
//======================================================

//======================================================
// C2类,用于判断两个数通过加减乘除运算能否得到某个结果
// C代表Caculate,2代表两个操作数
// op1:操作数1,op2:操作数2,result,结果
//======================================================
function C2(op1,op2,result){
var obj=new Object();
obj.op1=op1;
obj.op2=op2;
obj.result=result;

obj.findComputeMethods=function(){
    var micro=0.000001 // 定义一个极小量,运算结果绝对值小于它就算相等

    var arr=[];

    // op1+op2
    if(Math.abs(result-(op1+op2))<micro){
        arr.push(op1+"+"+op2);  
    }

    // op1*op2
    if(Math.abs(result-op1*op2)<micro){
        arr.push(op1+"*"+op2);  
    }

    // op1-op2
    if(Math.abs(result-(op1-op2))<micro){
        arr.push(op1+"-"+op2);  
    }

    // op2-op1
    if(Math.abs(result-(op2-op1))<micro){
        arr.push(op2+"-"+op1);  
    }

    // op1/op2
    if(Math.abs(result-op1/op2)<micro){
        arr.push(op1+"/"+op2);  
    }

    // op2/op1
    if(Math.abs(result-op2/op1)<micro){
        arr.push(op2+"/"+op1);  
    }

    return arr;
}

return obj;

}

//======================================================
// C3类,用于判断三个数通过加减乘除运算能否得到某个结果
// C代表Caculate,3代表三个操作数
// op1:操作数1,op2:操作数2,op3:操作数3,result,结果
//======================================================
function C3(op1,op2,op3,result){
var obj=new Object();
obj.op1=op1;
obj.op2=op2;
obj.op3=op3;
obj.result=result;

obj.findComputeMethods=function(){
    var retArr=[];// 最终返回数组

    // 排列数组,三个操作数共有6种排列方式
    var permutationArr=[ 
                        [this.op1,this.op2,this.op3],
                        [this.op1,this.op3,this.op2],
                        [this.op2,this.op1,this.op3],
                        [this.op2,this.op3,this.op1],
                        [this.op3,this.op2,this.op1],
                        [this.op3,this.op1,this.op2], 
                       ]; 

    for(var i=0;i<permutationArr.length;i++){
        var arr=permutationArr[i];
        var op1=arr[0];
        var op2=arr[1];
        var op3=arr[2];

        // [op1,op2]-op3
        var c2=new C2(op1,op2,this.result+op3);
        var methods=c2.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(‘(‘+methods[j]+")"+"-"+op3);
        }

        // [op1,op2]/op3
        c2=new C2(op1,op2,this.result*op3);
        methods=c2.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(‘(‘+methods[j]+")"+"/"+op3);
        }

        // [op1,op2]+op3
        c2=new C2(op1,op2,this.result-op3);
        methods=c2.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(‘(‘+methods[j]+")"+"+"+op3);
        }

        // op3-[op1,op2]
        c2=new C2(op1,op2,op3-this.result);
        methods=c2.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(op3+"-"+‘(‘+methods[j]+")");
        }

        // [op1,op2]*op3
        c2=new C2(op1,op2,this.result/op3);
        methods=c2.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(‘(‘+methods[j]+")"+"*"+op3);
        }

        // op3/[op1,op2]
        c2=new C2(op1,op2,op3/this.result);
        methods=c2.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(op3+"/"+‘(‘+methods[j]+")");
        }
    }

    return retArr;
};

return obj;

}

//======================================================
// C4类,用于判断三个数通过加减乘除运算能否得到某个结果
// C代表Caculate,4代表两个操作数
// op1:操作数1,op2:操作数2,op3:操作数3,op4:操作数4,result,结果
//======================================================
function C4(op1,op2,op3,op4,result){
var obj=new Object();
obj.op1=op1;
obj.op2=op2;
obj.op3=op3;
obj.op4=op4;
obj.result=result;

obj.findComputeMethods=function(){
    var retArr=[];// 返回数组

    var permutationArr=[    [this.op1,this.op2,this.op3,this.op4],
                         [this.op1,this.op2,this.op4,this.op3],
                         [this.op1,this.op3,this.op2,this.op4],
                         [this.op1,this.op3,this.op4,this.op2],
                         [this.op1,this.op4,this.op2,this.op3],
                         [this.op1,this.op4,this.op3,this.op2], 
                            [this.op2,this.op1,this.op3,this.op4],
                         [this.op2,this.op1,this.op4,this.op3],
                         [this.op2,this.op3,this.op1,this.op4],
                         [this.op2,this.op3,this.op4,this.op1],
                         [this.op2,this.op4,this.op1,this.op3],
                         [this.op2,this.op4,this.op3,this.op1], 
                            [this.op3,this.op1,this.op2,this.op4],
                         [this.op3,this.op1,this.op4,this.op2],
                         [this.op3,this.op2,this.op1,this.op4],
                         [this.op3,this.op2,this.op4,this.op1],
                         [this.op3,this.op4,this.op1,this.op2],
                         [this.op3,this.op4,this.op2,this.op1], 
                            [this.op4,this.op1,this.op2,this.op3],
                         [this.op4,this.op1,this.op3,this.op2],
                         [this.op4,this.op2,this.op1,this.op3],
                         [this.op4,this.op2,this.op3,this.op1],
                         [this.op4,this.op3,this.op1,this.op2],
                         [this.op4,this.op3,this.op2,this.op1], 
                       ]; // 全排列数组,四个操作数共有24种排列方式

    for(var i=0;i<permutationArr.length;i++){
        var arr=permutationArr[i];

        var op1=arr[0];
        var op2=arr[1];
        var op3=arr[2];
        var op4=arr[3];         

        // [op1,op2,op3]-op4
        var c3=new C3(op1,op2,op3,this.result+op4);
        var methods=c3.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(‘(‘+methods[j]+")"+"-"+op4);
        }

        // [op1,op2,op3]/op4
        var c3=new C3(op1,op2,op3,this.result*op4);
        var methods=c3.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(‘(‘+methods[j]+")"+"/"+op4);
        }

        // [op1,op2,op3]+op4
        var c3=new C3(op1,op2,op3,this.result-op4);
        var methods=c3.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(‘(‘+methods[j]+")"+"+"+op4);
        }

        // op4-[op1,op2,op3]
        var c3=new C3(op1,op2,op3,op4-this.result);
        var methods=c3.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(op4+"-"+‘(‘+methods[j]+")");
        }

        // [op1,op2,op3]*op4
        var c3=new C3(op1,op2,op3,this.result/op4);
        var methods=c3.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(‘(‘+methods[j]+")"+"*"+op4);
        }

        // op4/[op1,op2,op3]
        var c3=new C3(op1,op2,op3,op4/this.result);
        var methods=c3.findComputeMethods();
        for(var j=0;j<methods.length;j++){
            retArr.push(op4+"/"+‘(‘+methods[j]+")");
        }

        // 以下为C4中特有的先成对组合再看运算结果的六种情况
        // op1*op2-op3*op4
        if(op1*op2-op3*op4==result){
            retArr.push(op1+"*"+op2+"-"+op3+"*"+op4);
        }

        // op1*op2+op3*op4
        if(op1*op2+op3*op4==result){
            retArr.push(op1+"*"+op2+"+"+op3+"*"+op4);
        }

        // op1/op2-op3/op4
        if(op1/op2-op3/op4==result){
            retArr.push(op1+"/"+op2+"-"+op3+"/"+op4);
        }

        // op1/op2+op3/op4
        if(op1/op2+op3/op4==result){
            retArr.push(op1+"/"+op2+"+"+op3+"/"+op4);
        }

        // op1*op2-op3/op4
        if(op1*op2-op3/op4==result){
            retArr.push(op1+"*"+op2+"-"+op3+"/"+op4);
        }

        // op1*op2+op3/op4
        if(op1*op2+op3/op4==result){
            retArr.push(op1+"*"+op2+"+"+op3+"/"+op4);
        }
    }

    return retArr;
}

return obj;

}

//======================================================
// 用来得到仅包含不重复元素的数组
// arr:传入的数组
//======================================================
function getDistinctArray(arr){
var returnArr=new Array();

var sortedArr=arr.sort();
for(var i=0;i<sortedArr.length;i++){
    if(returnArr[returnArr.length-1]!=sortedArr[i]){
        returnArr.push(sortedArr[i]);
    }
}

return returnArr;

}

//======================================================
// 程序入口
//======================================================
function main(){
var RESULT=24 // 定义24这个结果

process.stdin.resume();    
process.stdout.write("\033[33m 请输入四个数字,用逗号分隔: \033[39m");// 草×××
process.stdin.setEncoding(‘utf8‘);

process.stdin.on(‘data‘,function(text){
    var input=text.trim();
    process.stdin.end();// 退出输入状态  

    var arrTemp=input.split(",");
    var op1=parseInt(arrTemp[0],10);
    var op2=parseInt(arrTemp[1],10);
    var op3=parseInt(arrTemp[2],10);
    var op4=parseInt(arrTemp[3],10);

    var c4=new C4(op1,op2,op3,op4,RESULT);
    var arr=getDistinctArray(c4.findComputeMethods());

    if(arr.length>0){
        for(var i=0;i<arr.length;i++){
            console.log(arr[i]+"="+RESULT); 
        }
    }else{
        console.log(input+"这四个数无法计算得到24");
    }
});

}

// 开始
main();

最后贴出点运行结果:
C:\Users\horn1\Desktop\node.js\51-60\56-算24c41.02>node c24.js
请输入四个数字,用逗号分隔: 11,13,2,5
11,13,2,5这四个数无法计算得到24

C:\Users\horn1\Desktop\node.js\51-60\56-算24c41.02>node c24.js
请输入四个数字,用逗号分隔: 12,34,6,3
((6/3)+34)-12=24
((6/3)-12)+34=24
(34-(12/3))-6=24
34-((12/3)+6)=24
34-(12-(6/3))=24

C:\Users\horn1\Desktop\node.js\51-60\56-算24c41.02>node c24.js
请输入四个数字,用逗号分隔: 3,3,7,7
((3/7)+3)*7=24

C:\Users\horn1\Desktop\node.js\51-60\56-算24c41.02>node c24.js
请输入四个数字,用逗号分隔: 13,5,6,7
((13+7)6)/5=24
((13+7)/5)
6=24
((13-7)5)-6=24
((5
6)+7)-13=24
((56)-13)+7=24
((6
5)+7)-13=24
((65)-13)+7=24
((6
7)-13)-5=24
((67)-5)-13=24
((7
6)-13)-5=24
((76)-5)-13=24
((7+13)
6)/5=24
((7+13)/5)6=24
6/(5/(13+7))=24
6/(5/(7+13))=24
7-(13-(5
6))=24
7-(13-(6*5))=24

计算24

标签:var   sorted   set   必须   数通   数值   fun   []   nod   

原文地址:https://blog.51cto.com/7726611/2356926

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!