例如,黑色40 + 2:目标42
有色5 3 6 2 4,你可以通过5 3 + 6 * 4 2 +获得目标 - (使用RPN,因为它避免使用括号)。
现在,当我们玩游戏时,我想用我的掌上电脑找到最佳答案。
我必须说我对解决方案并没有太多考虑,我只是寻找关于查找参数排列的部分,但是如何从中生成可能的表达式?我会使用RPN并枚举表达式的所有可能“形状”,然后使用+ - * /填充空白。
我不认识枚举表达式形状的问题。
输出将是这样的: ..... XXXX .... x.xxx ... x..xxx ..x ... XXX .... XX.XX ... x.x.xx ..x..x.xx ... xx..xx ..x.x..xx .... XXX.X ... x.xx.x ..x..xx.x ... xx.x.x ..x.x.x.x
像这样的事情: ..xx ... XX ... xxx..x ..x.xx..x ..x.xx..x 无效,因为第二个或第三个运算符会找到一个操作数。我可以使用硬编码列表,但它看起来真的很难看!
答案 0 :(得分:7)
我认为你正在寻找的是大小为5的完整二叉树的枚举。(这些对象的数量是第五个Catalan number,即14。)。根据加泰罗尼亚数字的标准递归,枚举是直截了当的:
对于每个(i,5-i),生成具有i
个叶子的所有树,并且所有具有5-i
的树叶,并且对于每个树的每个组合,构造通过创建一个根节点来生成一棵新树,该根节点的左子节点来自第一组,右子节点来自第二组。如果您不想使用树,请直接使用RPN:
# Produces all possible RPN layouts with n values and n-1 binary operators,
# representing values as '#' and operators as '+'
def RPN(n):
if n == 1:
yield '#'
for i in range(1,n):
for left in RPN(i):
for right in RPN(n - i):
yield left + right + '+'
当然,也有一元运营商。如果你允许这些,它会变得更复杂。
请注意,您可以直接调整以上内容直接插入参数;而不是将n分成(i,n-i),你会发现n个值集合的所有分区成为两个非空子集。 (否则,您可以找到该组数字的所有排列,并将它们插入到生成的RPN表达式中。)
然后你需要做的“全部”是插入所有可能的操作符序列(如果你只允许+, - ,*和/那么你有4个 4 = 256种可能性)。
因此,如果五个数字不同,那么最终会得到14 * 5! * 4 4 = 430080表达式进行测试。
答案 1 :(得分:0)
枚举不同数字块数的问题是您可以应用于集合http://en.wikipedia.org/wiki/Partition_of_a_set的分区数