扑克牌速算24 -穷举(JavaScript)

简介: 从扑克牌里面任意抽取4张(无重复)A(1)2345678910J(11)Q(12)K(13),请给出通过4则运算,使结果为24的算法,并且每个数在算式中使用一次。如果无法通过上述规则得到24,则输出“无法计算得到24”。

从扑克牌里面任意抽取4张(无重复)A(1)2345678910J(11)Q(12)K(13),请给出通过4则运算,使结果为24的算法,并且每个数在算式中使用一次。如果无法通过上述规则得到24,则输出“无法计算得到24”。



如果给出4个数为2 3 4 5,程序的输出结果应是一个表达式:(5+3-2)*4

要求:提交算法思路即可。


思路:


先分析一下穷举包含多少种情况:


1、操作数。由于是给定的4张牌,所以把这个4张牌进行全排列,共有:24种

2、运算符。4个数之间有3个运算符,每个运算符有4种选择,共有:64种

3、运算符优先级。共有:5种


统计上面的情况,应该总共有:24645=7680种


即如果用ab、c、d代表这四个数,&代表某一种运算符,优先级依然用括号表示,那么只需要分别考虑以下这些形式:


1、(a & b) & (c & d)

2、((a & b) & c) & d

3、(a & (b & c)) & d

4、a & (b & (c & d))

5、a & ((b & c) & d)


## 解题代码

const get24 = (str) => {
   let arr = str.split(' ')
   let transfer = (v) => {
       switch (v) {
           case 'A':
               return 1
           case 'J':
               return 11
           case 'Q':
               return 12
           case 'K':
               return 13
           default:
               return Number(v)
       }
   }
   //1.转换成真实数字
   let nums = []
   for (let i = 0; i < arr.length; i++) {
       nums[i] = transfer(arr[i])
   }
   //2.全排列-穷举不重复的排列-回溯
   let ans = [];
   let used = Array(nums.length).fill(false)
   let backTracing = (start, path) => {
       if (start === nums.length) {
           ans.push(path.slice())
           return
       }
       for (let i = 0; i < nums.length; ++i) {
           if (used[i] || (i > 0 && nums[i] === nums[i - 1] && !used[i - 1])) {
               continue;
           }
           path.push(nums[i])
           used[i] = true
           backTracing(start + 1, path)
           used[i] = false
           path.pop()
       }
   }
   nums.sort((a, b) => a - b)
   backTracing(0, [])
   /* 
   */
   //3.选择路径-穷举
   let dict = ['+', '-', '*', '/']
   for (let i = 0; i < ans.length; i++) {
       for (let a = 0; a < 4; a++) {
           for (let b = 0; b < 4; b++) {
               for (let c = 0; c < 4; c++) {
                   //(1-2)-3-4
                   let sum1 = eval(`(${ans[i][0]}${dict[a]}${ans[i][1]})${dict[b]}${ans[i][2]}${dict[c]}${ans[i][3]}`)
                   //1-(2-3)-4
                   let sum2 = eval(`${ans[i][0]}${dict[a]}(${ans[i][1]}${dict[b]}${ans[i][2]})${dict[c]}${ans[i][3]}`)
                   //1-2-(3-4)
                   let sum3 = eval(`${ans[i][0]}${dict[a]}${ans[i][1]}${dict[b]}(${ans[i][2]}${dict[c]}${ans[i][3]})`)
                   // (1-2-3)-4
                   let sum4 = eval(`(${ans[i][0]}${dict[a]}${ans[i][1]}${dict[b]}${ans[i][2]})${dict[c]}${ans[i][3]}`)
                   //1-(2-3-4)
                   let sum5 = eval(`${ans[i][0]}${dict[a]}(${ans[i][1]}${dict[b]}${ans[i][2]}${dict[c]}${ans[i][3]})`)
                   //(1-2)-(3-4)
                   let sum6 = eval(`(${ans[i][0]}${dict[a]}${ans[i][1]})${dict[b]}(${ans[i][2]}${dict[c]}${ans[i][3]})`)
                   // 1-((2-3)-4)
                   let sum7 = eval(`${ans[i][0]}${dict[a]}((${ans[i][1]}${dict[b]}${ans[i][2]})${dict[c]}${ans[i][3]})`)
                   //((1-2)-3)-4
                   let sum8 = eval(`((${ans[i][0]}${dict[a]}${ans[i][1]})${dict[b]}${ans[i][2]})${dict[c]}${ans[i][3]}`)
                   // 1-(2-(3-4))
                   let sum9 = eval(`${ans[i][0]}${dict[a]}(${ans[i][1]}${dict[b]}(${ans[i][2]}${dict[c]}${ans[i][3]}))`)
                   // 1-((2-3)-4)
                   let sum10 = eval(`${ans[i][0]}${dict[a]}((${ans[i][1]}${dict[b]}${ans[i][2]})${dict[c]}${ans[i][3]})`)
                   if ([sum1, sum2, sum3, sum4, sum5, sum6, sum7, sum8, sum9, sum10].includes(24)) {
                       return "YES"
                   }
               }
           }
       }
   }
   return "NO"
}
let str = 'A 2 3 6'
let str1 = '3 3 8 8'
console.log(get24(str))
console.log(get24(str1))
相关文章
|
机器学习/深度学习 JavaScript 前端开发
LeetCode 51.N皇后(JavaScript 解题)
LeetCode 51.N皇后(JavaScript 解题)
64 0
|
7月前
|
算法 JavaScript
js经典算法题,鸡兔同笼问题,鸡兔共35只,共94只脚,问鸡和兔子一共有多少只?(详细解答)
js经典算法题,鸡兔同笼问题,鸡兔共35只,共94只脚,问鸡和兔子一共有多少只?(详细解答)
249 0
|
7月前
|
JavaScript 前端开发
JavaScript题解剑指offer : 11. 旋转数组的最小数字
JavaScript题解剑指offer : 11. 旋转数组的最小数字
46 0
|
JavaScript 前端开发
【LeetCode】JavaScript题解:电话号码的字母组合|组合总和Ⅲ
【LeetCode】JavaScript题解:电话号码的字母组合|组合总和Ⅲ
|
前端开发 算法 JavaScript
LeetCode宝石与石头使用JavaScript解题|前端学算法
LeetCode宝石与石头使用JavaScript解题|前端学算法
109 0
LeetCode宝石与石头使用JavaScript解题|前端学算法
|
前端开发 JavaScript 算法
LeetCode分割字符串的最大得分使用JavaScript解题,击败了100%的用户|前端学算法
LeetCode分割字符串的最大得分使用JavaScript解题,击败了100%的用户|前端学算法
109 0
LeetCode分割字符串的最大得分使用JavaScript解题,击败了100%的用户|前端学算法
|
存储 前端开发 算法
LeetCode回文数使用JavaScript解题,一种不太正经的解法|前端学算法
LeetCode回文数使用JavaScript解题,一种不太正经的解法|前端学算法
79 0
LeetCode回文数使用JavaScript解题,一种不太正经的解法|前端学算法
|
前端开发 算法 JavaScript
LeetCode最长公共前缀使用JavaScript解题,一种不太正经的解法|前端学算法
LeetCode最长公共前缀使用JavaScript解题,一种不太正经的解法|前端学算法
116 0
LeetCode最长公共前缀使用JavaScript解题,一种不太正经的解法|前端学算法
|
JavaScript 前端开发
从JavaScript二维数组排序说开去(1)
从JavaScript二维数组排序说开去(1)
146 1
|
JavaScript 前端开发
从JavaScript二维数组排序说开去(2)
从JavaScript二维数组排序说开去(2)
1800 1