24point.js 2.8 KB

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