24点游戏,JS实现

549 阅读1分钟

最粗暴简单的解法就是穷举法,在这里就不展示穷举法的code了,没有什么价值~下面介绍的是在编程之美这本书中,书的作者提的一个思路。通过分治的思想,以及创建一个运算集合(保留a+b,b+a这种结果一致的运算中的一个),去设计代码。我的JS实现也是参照网上其他语言的实现改的~下面就贴出JS代码。

    function node(value, exp) {
       this.value = value;
       this.exp = exp;
    }
    function equalTo24(arr) {
      let answers = new Set();
      let S = new Map();
      let A = arr;

      function run() {
        for (var i = 0; i < (1 << 4); i++) {
          let set = new Set();
          S.set(i, set);
        }
        for (var i = 0; i < 4; i++) {
          let n = new node(A[i], A[i] + "");
          let set = new Set();
          set.add(n);
          S.set(1 << i, set);
        }
        for (var i = 1; i < (1 << 4); i++) {
          fork(i);
        }

        let mSet = S.get((1 << 4) - 1);
        for (let v of mSet.values()) {
          if (v.value == 24) {
            answers.add(v.exp);
          }
        }
        if (answers.size == 0) {
          console.log("It's no possible");
        }
        else {
          for (let i of answers) {
            console.log(i)
          }
        }
      }

      function fork(m) {
        var mSet = S.get(m);
        if (mSet.size > 0)
          return mSet;
        else {
          for (var x = 1; x < m; x++) {
            if ((x & m) == x) {
              let s1 = fork(x);
              let s2 = fork(m - x);
              for (let n1 of s1)
                for (let n2 of s2) {
                  var str = "(" + n1.exp + "+" + n2.exp + ")";
                  mSet.add(new node(n1.value + n2.value, str));
                  str = "(" + n1.exp + "-" + n2.exp + ")";
                  mSet.add(new node(n1.value - n2.value, str));
                  str = "(" + n2.exp + "-" + n1.exp + ")";
                  mSet.add(new node(n2.value - n1.value, str));
                  str = "(" + n1.exp + "*" + n2.exp + ")";
                  mSet.add(new node(n1.value * n2.value, str));
                  if (n1.value != 0) {
                    str = "(" + n2.exp + "/" + n1.exp + ")";
                    mSet.add(new node(n2.value / n1.value, str));
                  }
                  if (n2.value != 0) {
                    str = "(" + n1.exp + "/" + n2.exp + ")";
                    mSet.add(new node(n1.value / n2.value, str));
                  }
                }
            }
          }
          return mSet;
        }

      }
      run()
    }

测试的Case:

var arr = [12,40,5,6];
equalTo24(arr)
(12*((40/5)-6))
(12*(6-(40/5)))
((12-(40/5))*6)
(((40/5)-12)*6)
(6*(12-(40/5)))
(6*((40/5)-12))
(((40/5)-6)*12)
((6-(40/5))*12)