24point.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /* eslint-disable semi */
  2. function solve24point(...numbers) {
  3. class Operation {
  4. constructor(val, rank, exp) {
  5. this.val = val;
  6. this.rank = rank;
  7. this.exp = exp;
  8. }
  9. plus(that) {
  10. return new Operation(this.val + that.val, 0, `${this.exp}+${that.exp}`);
  11. }
  12. minus(that) {
  13. let exp;
  14. if (that.rank === 0) exp = `${this.exp}-(${that.exp})`;
  15. else exp = `${this.exp}-${that.exp}`;
  16. return new Operation(this.val - that.val, 0, exp);
  17. }
  18. mult(that) {
  19. let exp;
  20. if (this.rank === 0 && that.rank === 0) exp = `(${this.exp})*(${that.exp})`;
  21. else if (this.rank === 0) exp = `(${this.exp})*${that.exp}`;
  22. else if (that.rank === 0) exp = `${this.exp}*(${that.exp})`;
  23. else exp = `${this.exp}*${that.exp}`;
  24. return new Operation(this.val * that.val, 1, exp);
  25. }
  26. div(that) {
  27. let exp;
  28. if (this.rank === 0 && that.rank !== 2) exp = `(${this.exp})/(${that.exp})`;
  29. else if (this.rank === 0) exp = `(${this.exp})/${that.exp}`;
  30. else if (that.rank !== 2) exp = `${this.exp}/(${that.exp})`;
  31. else exp = `${this.exp}/${that.exp}`;
  32. return new Operation(this.val / that.val, 1, exp);
  33. }
  34. }
  35. const eps = 0.000001;
  36. function dfs(nums) {
  37. if (nums.length === 1 && Math.abs(nums[0].val - 24.0) < eps) return nums[0].exp;
  38. for (let i = 0; i < nums.length - 1; i++) {
  39. for (let j = i + 1; j < nums.length; j++) {
  40. let next = new Array(nums.length - 2);
  41. for (let k = 0, idx = 0; k < nums.length; k++) {
  42. if (k == i || k == j) continue;
  43. next[idx++] = nums[k];
  44. }
  45. let p = nums[i], q = nums[j];
  46. let tmp = [p.plus(q), p.minus(q), q.minus(p), p.mult(q)];
  47. if (q.val > 0) tmp.push(p.div(q));
  48. if (p.val > 0) tmp.push(q.div(p));
  49. for (let i = 0; i < tmp.length; i++) {
  50. next.push(tmp[i]);
  51. const res = dfs(next);
  52. if (res !== null) return res;
  53. next.pop();
  54. }
  55. }
  56. }
  57. return null;
  58. }
  59. const nums = new Array(numbers.length);
  60. for (let i = 0; i < numbers.length; i++) {
  61. nums[i] = new Operation(numbers[i], 2, numbers[i]);
  62. }
  63. return dfs(nums);
  64. }
  65. // eslint-disable-next-line no-console
  66. const log = console.log.bind(console);
  67. log(solve24point(2, 4, 1, 8));
  68. log(solve24point(2, 4, 6, 8));
  69. log(solve24point(1, 2, 5, 8));
  70. log(solve24point(1, 7, 8, 8));
  71. log(solve24point(6, 6, 6, 6, 6));
  72. log(solve24point(1, 5, 5, 5));
  73. log(solve24point(2, 5, 5, 10));
  74. log(solve24point(1, 4, 5, 6));
  75. log(solve24point(6, 9, 9, 10));