Scala二十四点游戏(7):穷举可能的表达式

jerry Scala 2015年11月25日 收藏

详细的算法说明可以参考24点算法之我见,简单的穷举可以把+,-,×,/和()和四个数进行全排列,但这样会出现很多无效的表达式,因此我们这里参考“24点算法之我见”的算法,对表达式做些分析:

“换一种思路,介绍我的24点的穷举法
上面的算法是对数和运算符进行穷举和搜索

我的算法是对运算式进行穷举
无论给什么样的是4个数,运算式总是不变的,举例来说:

N+N+N+N=24,这是一种运算式
N*N+N*N=24,这是另一种运算式
N/(N-N/N)=24,这又是另一种运算式

下面这个例子:
N+N-(N-N)=24
N+N-N+N=24

上面虽然是两种不同的运算式,但本质是同一种运算式(肯定同时成立或同时不成立),穷举的时候只要穷举其中一个就行了

再看下面这个例子
N/(N+N+N)=24
虽然是一个运算式,但是这个运算式是不可能成立的,也就是无解运算式,穷举的时候是不需要穷举该运算式的

参考该文章提供的表格,我们可以定义如下两个List对象(去掉无解的表达式)

所有合法的表达式的模板:

  1. val templates=List(
  2. "(N-(N+N))*N",
  3. "(N-(N-N))*N",
  4. "(N*N+N)*N",
  5. "(N*N+N)/N",
  6. "(N*N-N)*N",
  7. "(N*N-N)/N",
  8. "(N/N+N)*N",
  9. "(N/N-N)*N",
  10. "(N+N)*(N+N)",
  11. "(N+N)*(N-N)",
  12. "(N+N)*N*N",
  13. "(N+N)*N/N",
  14. "(N+N)*N+N",
  15. "(N+N)*N-N",
  16. "(N+N)/(N/N)",
  17. "(N+N)/N*N",
  18. "(N+N)/N+N",
  19. "(N+N*N)*N",
  20. "(N+N*N)/N",
  21. "(N+N/N)*N",
  22. "(N+N+N)*N",
  23. "(N+N+N)/N",
  24. "(N+N-N)*N",
  25. "(N-N)*(N+N)",
  26. "(N-N)*(N-N)",
  27. "(N-N)*N*N",
  28. "(N-N)*N/N",
  29. "(N-N)*N+N",
  30. "(N-N)*N-N",
  31. "(N-N)/(N/N)",
  32. "(N-N)/N*N",
  33. "(N-N*N)*N",
  34. "(N-N/N)*N",
  35. "(N-N+N)*N",
  36. "(N-N-N)*N",
  37. "N-(N-N)*N",
  38. "N-(N-N)+N",
  39. "N-(N-N-N)",
  40. "N*(N-(N+N))",
  41. "N*(N-(N-N))",
  42. "N*(N*N+N)",
  43. "N*(N*N-N)",
  44. "N*(N/N+N)",
  45. "N*(N/N-N)",
  46. "N*(N+N)*N",
  47. "N*(N+N)/N",
  48. "N*(N+N)+N",
  49. "N*(N+N)-N",
  50. "N*(N+N*N)",
  51. "N*(N+N/N)",
  52. "N*(N+N+N)",
  53. "N*(N+N-N)",
  54. "N*(N-N)*N",
  55. "N*(N-N)/N",
  56. "N*(N-N)+N",
  57. "N*(N-N)-N",
  58. "N*(N-N*N)",
  59. "N*(N-N/N)",
  60. "N*(N-N+N)",
  61. "N*(N-N-N)",
  62. "N*N-(N+N)",
  63. "N*N-(N-N)",
  64. "N*N*(N+N)",
  65. "N*N*(N-N)",
  66. "N*N*N*N",
  67. "N*N*N/N",
  68. "N*N*N+N",
  69. "N*N*N-N",
  70. "N*N/(N*N)",
  71. "N*N/(N/N)",
  72. "N*N/(N+N)",
  73. "N*N/(N-N)",
  74. "N*N/N*N",
  75. "N*N/N/N",
  76. "N*N/N+N",
  77. "N*N/N-N",
  78. "N*N+N*N",
  79. "N*N+N/N",
  80. "N*N+N+N",
  81. "N*N+N-N",
  82. "N*N-N*N",
  83. "N*N-N/N",
  84. "N*N-N+N",
  85. "N*N-N-N",
  86. "N/((N+N)/N)",
  87. "N/((N-N)/N)",
  88. "N/(N*N)*N",
  89. "N/(N*N/N)",
  90. "N/(N/(N+N))",
  91. "N/(N/(N-N))",
  92. "N/(N/N)*N",
  93. "N/(N/N)/N",
  94. "N/(N/N*N)",
  95. "N/(N/N/N)",
  96. "N/(N/N-N)",
  97. "N/(N+N)*N",
  98. "N/(N-N)*N",
  99. "N/(N-N/N)",
  100. "N/N*(N+N)",
  101. "N/N*(N-N)",
  102. "N/N*N*N",
  103. "N/N*N/N",
  104. "N/N*N+N",
  105. "N/N*N-N",
  106. "N/N/(N/N)",
  107. "N/N/N*N",
  108. "N/N+N*N",
  109. "N/N+N+N",
  110. "N+(N+N)*N",
  111. "N+(N+N)/N",
  112. "N+(N-N)*N",
  113. "N+N-(N-N)",
  114. "N+N*(N+N)",
  115. "N+N*(N-N)",
  116. "N+N*N*N",
  117. "N+N*N/N",
  118. "N+N*N+N",
  119. "N+N*N-N",
  120. "N+N/(N/N)",
  121. "N+N/N*N",
  122. "N+N/N+N",
  123. "N+N+N*N",
  124. "N+N+N/N",
  125. "N+N+N+N",
  126. "N+N+N-N",
  127. "N+N-N+N",
  128. "N+N-N-N",
  129. "N-N*(N-N)",
  130. "N-N+N*N",
  131. "N-N+N+N"
  132.  
  133. )
  134.  

等价表达式的定义:

  1. val equivalence = List(
  2. "N+N-N+N,N+N+N-N",
  3. "N+N-(N-N),N+N-N+N,N+N+N-N",
  4. "N+N*(N+N),(N+N)*N+N",
  5. "N+N*(N-N),N+(N-N)*N",
  6. "N+N/N*N,N+N*N/N",
  7. "(N+N)/N*N,(N+N)*N/N",
  8. "N+N/(N/N),N+N/N*N,N+N*N/N",
  9. "(N+N)/(N/N),(N+N)/N*N,(N+N)*N/N",
  10. "N-N+N+N,N+N+N-N",
  11. "N-N+N*N,N+N*N-N",
  12. "(N-N+N)*N,(N+N-N)*N",
  13. "(N-(N+N))*N,(N-N-N)*N",
  14. "N-(N-N)+N,N-N+N+N,N+N+N-N",
  15. "N+N-N-N,N-N+N+N,N+N+N-N",
  16. "N-(N-N-N),N-N+N+N,N+N+N-N",
  17. "N-(N-N)*N,N+(N-N)*N",
  18. "(N-(N-N))*N,(N-N+N)*N,(N+N-N)*N",
  19. "(N-N)*N+N,N+(N-N)*N",
  20. "(N-N)*(N+N),(N+N)*(N-N)",
  21. "N-N*(N-N),N+N*(N-N),N+(N-N)*N",
  22. "(N-N)/N*N,(N-N)*N/N",
  23. "(N-N)/(N/N),(N-N)/N*N,(N-N)*N/N",
  24. "N*N+N+N,N+N+N*N",
  25. "N*(N+N)+N,N+(N+N)*N",
  26. "N*(N+N+N),(N+N+N)*N",
  27. "N*N+N-N,N-N+N*N",
  28. "N*(N+N)-N,(N+N)*N-N",
  29. "N*(N+N-N),(N+N-N)*N",
  30. "N*(N+N)*N,(N+N)*N*N",
  31. "(N*N+N)*N,(N+N*N)*N",
  32. "N*(N+N*N),(N+N*N)*N",
  33. "N*(N+N)/N,(N+N)*N/N",
  34. "(N*N+N)/N,(N+N*N)/N",
  35. "N*(N+N/N),(N+N/N)*N",
  36. "N*N-N+N,N-N+N*N",
  37. "N*(N-N)+N,N+(N-N)*N",
  38. "N*(N-N+N),(N+N-N)*N",
  39. "N*N-(N+N),N*N-N-N",
  40. "N*(N-(N+N)),N*(N-N-N),(N-N-N)*N",
  41. "N*(N-N)-N,(N-N)*N-N",
  42. "N*(N-N-N),(N-N-N)*N",
  43. "N*N-(N-N),N*N-N+N,N-N+N*N",
  44. "N*(N-(N-N)),N*(N-N+N),(N+N-N)*N",
  45. "N*(N-N)*N,(N-N)*N*N",
  46. "N*(N-N*N),(N-N*N)*N",
  47. "N*(N-N)/N,(N-M2)*N/N",
  48. "N*(N-N/N),(N-N/N)*N",
  49. "N*N*N+N,N+N*N*N",
  50. "N*N*(N+N),(N+N)*N*N",
  51. "N*(N*N+N),(N+N*N)*N",
  52. "N*N*(N-N),(N-N)*N*N",
  53. "N*(N*N-N),(N*N-N)*N",
  54. "N*N/N+N,N+N*N/N",
  55. "N*(N/N+N),(N+N/N)*N",
  56. "N*N/N*N,N*N*N/N",
  57. "N*N/(N*N),N*N/N/N",
  58. "N*N/(N/N),N*N/N*N,N*N*N/N",
  59. "N/N+N+N,N+N+N/N",
  60. "N/N+N*N,N*N+N/N",
  61. "N/(N+N)*N,N*N/(N+N)",
  62. "(N/N+N)*N,(N+N/N)*N",
  63. "N/((N+N)/N),N/(N+N)*N,N*N/(N+N)",
  64. "N/(N-N)*N,N*N/(N-N)",
  65. "N/((N-N)/N),N/(N-N)*N,N*N/(N-N)",
  66. "N/N*N+N,N+N*N/N",
  67. "N/N*(N+N),(N+N)*N/N",
  68. "N/N*N-N,N*N/N-N",
  69. "N/N*(N-N),N*(N-N)/N",
  70. "N/N*N*N,N*N*N/N",
  71. "N/(N*N)*N,N/N/N*N,N*N/N/N",
  72. "N/N*N/N,N*N/N/N",
  73. "N/(N*N/N),N/N/N*N,N*N/N/N",
  74. "N/(N/(N+N)),N/N*(N+N),(N+N)*N/N",
  75. "N/(N/(N-N)),N/N*(N-N),(N-N)*N/N",
  76. "N/N/N*N,N*N/N/N",
  77. "N/(N/N)*N,N/N*N*N,N*N*N/N",
  78. "N/(N/N*N),N/N*N/N,N*N/N/N",
  79. "N/N/(N/N),N/N/N*N,N*N/N/N",
  80. "N/(N/N)/N,N/N*N/N,N*N/N/N",
  81. "N/(N/N/N),N/N*N/N,N*N/N/N"
  82. )

通过这两个List对象,我们去掉等价的表达式,得出最终的合法表达式只有73种,大大缩小了需要穷举的表达式的数目:

  1. val templates=List(
  2. "N*N-N+N",
  3. "(N-N)*N*N",
  4. "N*N+N*N",
  5. "(N+N)*N*N",
  6. "N*N*N*N",
  7. "(N+N*N)*N",
  8. "(N*N-N)*N",
  9. "N*N+N+N",
  10. "(N/N-N)*N",
  11. "(N-(N-N))*N",
  12. "N-(N-N-N)",
  13. "N+N-(N-N)",
  14. "N*(N/N-N)",
  15. "(N-N*N)*N",
  16. "N*(N-N)+N",
  17. "N+N+N/N",
  18. "(N-N)*(N-N)",
  19. "N+N*N/N",
  20. "N*N/(N-N)",
  21. "(N+N)*(N+N)",
  22. "(N-N)*N/N",
  23. "N+(N+N)/N",
  24. "N*N/(N+N)",
  25. "(N+N)*N/N",
  26. "(N*N+N)*N",
  27. "(N*N-N)/N",
  28. "(N/N+N)*N",
  29. "N*N/N/N",
  30. "N+N+N-N",
  31. "N-(N-N)+N",
  32. "N/(N-N/N)",
  33. "N+(N-N)*N",
  34. "(N+N+N)*N",
  35. "N+N*N-N",
  36. "N*N-N/N",
  37. "(N+N)*N-N",
  38. "(N+N)*(N-N)",
  39. "(N-N/N)*N",
  40. "N*(N+N)+N",
  41. "N*N+N/N",
  42. "N*N/N-N",
  43. "(N+N/N)*N",
  44. "N*N*N/N",
  45. "(N+N*N)/N",
  46. "N+N*N+N",
  47. "N-(N-N)*N",
  48. "(N-(N+N))*N",
  49. "N*N-N-N",
  50. "N+N/N+N",
  51. "(N-N)*N-N",
  52. "(N+N)/N+N",
  53. "N*N+N-N",
  54. "N/N+N+N",
  55. "N*N*N-N",
  56. "(N*N+N)/N",
  57. "N+N+N*N",
  58. "N*(N-N)/N",
  59. "N/N*N+N",
  60. "N+N*N*N",
  61. "N+N+N+N",
  62. "N*N/(N*N)",
  63. "N+(N+N)*N",
  64. "(N-N)*N+N",
  65. "(N+N+N)/N",
  66. "(N+N)*N+N",
  67. "N*N*N+N",
  68. "N*N-(N-N)",
  69. "N*N-(N+N)",
  70. "(N-N-N)*N",
  71. "N*N/N+N",
  72. "(N+N-N)*N",
  73. "N/(N/N-N)",
  74. "N*N-N*N"
  75. )