惰性序列在消耗堆栈的递归调用中不起作用
Lazy sequence doesn't work in stack-consuming recursive calls
我找到了一个简单(但效率低下)的解决方案,在 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 部分中的表单仅被评估一次。 (即其中有 6 个值的 filter
表单仅针对它的第一个值进行迭代!)
我也尝试在 for
形式上使用 doall
,从而强制计算它,但是递归调用到达第一个形式的那一刻(当条件 (= n 1)
成立时)结果表达式(在本例中为 (if (some #{x} ds) 1 0)
形式的 1)作为整个调用链的结果返回。
这对我来说没有意义。
也许我犯了一个大错误或者这是 Clojure 中的错误?
注意:此函数应该计算数字 7 可以写成来自特定不同数字的另外 2 个数字之和的方式数(在本例中 #{1 2 3 4 5 6}
)。
我很想弄清楚这里发生了什么,因为这个函数可以用 loop
形式编写。
您的过滤谓词 #(< % n)
旨在从可用加数集中删除大于剩余目标总和的数字,而是测试小于加数 [=11] 的加数=].请尝试使用 #(< % x)
。
我找到了一个简单(但效率低下)的解决方案,在 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 部分中的表单仅被评估一次。 (即其中有 6 个值的 filter
表单仅针对它的第一个值进行迭代!)
我也尝试在 for
形式上使用 doall
,从而强制计算它,但是递归调用到达第一个形式的那一刻(当条件 (= n 1)
成立时)结果表达式(在本例中为 (if (some #{x} ds) 1 0)
形式的 1)作为整个调用链的结果返回。
这对我来说没有意义。
也许我犯了一个大错误或者这是 Clojure 中的错误?
注意:此函数应该计算数字 7 可以写成来自特定不同数字的另外 2 个数字之和的方式数(在本例中 #{1 2 3 4 5 6}
)。
我很想弄清楚这里发生了什么,因为这个函数可以用 loop
形式编写。
您的过滤谓词 #(< % n)
旨在从可用加数集中删除大于剩余目标总和的数字,而是测试小于加数 [=11] 的加数=].请尝试使用 #(< % x)
。