前言
休息的时候无意间看到群里有人发出了华为的校招题,一开始看题目的时候觉得很简单,于是晚上就试着写了一下,结果写的过程中打脸,不断的整理逻辑不断的重写,但我的性格又是不做出来晚上睡不好的那种,于是在做出来的时候就分享给大家(快凌晨三点了有木有,这校招题难度都达到这级别了?o(╥﹏╥)o)
题目描述
审题要注意:1+2+3*4是前面三个已经相加为6再乘4,没有括号!!
代码:
21点//牌和对应的权重
const pokerBox=["A","2","3","4","5","6","7","8","9","10","J","Q","K"];//下标+1刚好就是对应的分值
let calcSym=[0,1,2,3,4,5,6,7,8,9];//0,1,2 3,4 5,6,7 8,9分别对应+-*/
functionCalculate(a, b, c) {if(c<= 2)returna+b;if(c<= 4)returna-b;if(c<= 7)returna*b;if(c<= 9)returna/b;return -1;
}functionfilter(c) {if(c<= 2)return "+";if(c<= 4)return "-";if(c<= 7)return "*";if(c<= 9)return "/";return;
}
let answer= "NONE";//回复的字符串 默认回复NONE,表示无解
functionCalculate24(a, b, c, d, C1, C2, C3) {
let sum=Calculate(Calculate(Calculate(a, b, C1), c, C2), d, C3);if(sum=== 24) answer=`公式为:${a} ${filter(C1)} ${b} ${filter(C2)} ${c} ${filter(C3)} ${d}=${sum}`;returnsum;
}//全排列
//这里的全排序就是把原先的数组复制一个出来,然后新数组代替原先数组删除该值,temp数组添加该值,当新数组的长度为0,说明转移完成,就把temp数组放入matrix数组中
functionpermutation(pokers) {
let matrix=[];
const subFunc=(arr, temp)=>{if(temp.length> 4) temp.length= 4;//为了避免过长
if(arr.length=== 0) matrix.push(temp);
arr.forEach((elem, i)=>{
subFunc([...arr.slice(0, i), ...arr.slice(i+ 1)], [...temp, elem]);
});
}
subFunc(pokers, []);returnmatrix;
};//计算总数为24
functionCount24(a, b, c, d) {
calcSym.sort((x, y)=>x-y);//升序排序
if(Calculate24(a, b, c, d, calcSym[0], calcSym[1], calcSym[2])=== 24)return true;//第一次判断如果符合就不需要执行下面的循环了
let i= 1;//上面判断了一次,因此这里从1开始
if(calcSym.length<= 10) calcSym=[...newSet(permutation(calcSym).flatMap(item=>item.join()))].map(item=>item.split(","));//二维数组去重,并获取全排的数组(即每一种可能性)
while(true) {if(Calculate24(a, b, c, d, calcSym[i][0], calcSym[i][1], calcSym[i][2])=== 24)return true;if(i
};return false;
}functioninit() {if(calcSym.length=== 12) calcSym=permutation(calcSym);//获取全排的数组(即每一种可能性)
}
init();//初始化就立即执行
//对输入的数字进行一次全排
functioncalcNumber(arr) {if(Count24(arr[0], arr[1], arr[2], arr[3]))return true;//这一步满足那么下面就不用执行permutation了,因为底层是递归,很消耗性能
let i= 1;if(arr.length<= 4) arr=[...newSet(permutation(arr).flatMap(item=>item.join()))].map(item=>item.split(","));//二维数组去重
if(arr.length> 1) {while(true) {if(Count24(arr[i][0], arr[i][1], arr[i][2], arr[i][3]))return true;if(i
}
};returnanswer= "NONE";
}//当我输入完光标离开的时候就开始判断并计算
functionpokers(event) {
let arr=event.value.trim().split(" ");if(arr.length> 4) {
arr.length= 4;
document.getElementById("poker").value=arr.join(‘ ‘);
alert("您输入的牌数大于4张,这边自动帮您删除");
}if(arr.some(item=> !pokerBox.includes(item))) alert("ERROR");else{
let arrNew=arr.map(item=>{returnpokerBox.indexOf(item)+ 1});//计算权重
calcNumber(arrNew);//执行计算
}
}functiondialog() { alert(answer) };