我找到了一个简单(但效率低)的问题解决方案,基本上可以在Clojure中这样编写:
(defn make-someof [data]
(fn sumf
([x n ds]
(if (= n 1)
(if (some #{x} ds) 1 0)
(reduce + (for [m (filter #(< % n) ds)]
(sumf (- x m) (dec n) (disj ds m))))))
([x n] (sumf x n data))))
可以像这样调用:
((make-someof #{1 2 3 4 5 6}) 7 2)
但事实证明,make-sumof
函数的reduce部分中的表单只被评估一次。 (即filter
形式中有6个值只能为它的第一个值迭代!)
我也尝试在doall
表单上使用for
,从而强制它被计算,但是递归调用到达第一个表单时(当条件(= n 1)
被保持时)结果表达式(在本例中为(if (some #{x} ds) 1 0)
形式中的1)作为整个调用链的结果返回。
这对我来说没有意义 也许我犯了一个大错误,或者这是Clojure中的一个错误?
注意:此函数应该计算数字7可以写成的方式的数量,作为来自特定不同数字的2个其他数字的总和(在这种情况下为#{1 2 3 4 5 6}
)。
/>
我很想弄清楚这里发生了什么,因为这个函数可以用loop
形式编写。
答案 0 :(得分:2)
您的过滤谓词#(< % n)
旨在从大于剩余目标总和的可用加数集中删除数字,而是测试小于加数n
的加数。请尝试使用#(< % x)
。