【发布时间】:2014-10-30 17:20:51
【问题描述】:
尝试解决计算满足某些谓词的组合(重复)计数的任务,例如元素的相等性总和为给定数:
countChange :: Integer -> [Integer] -> Integer
countChange n xs = fromIntegral . length $ filter ((== n) . sum) $
concatMap (comb xs) [1..n]
where
comb _ 0 = [[]]
comb xs k = [y:ys | l@(y:xs') <- tails xs, ys <- comb l (k-1)]
上述幼稚方法存在一个显着的性能问题,即递归调用comb 反复重新计算k-1 个组合。
我想通过使用最小不动点来添加结果记忆,即。由Data.Function.fix 。
我已经添加了一个自递归函数的声明,但是失去了如何实现memoize 函数的想法:
countChange :: Integer -> [Integer] -> Integer
countChange n xs = fromIntegral . length $ filter ((== n) . sum) $
concatMap (fix (memoize . comb) xs) [1..n]
where
comb _ _ 0 = [[]]
comb xs f k = [y:ys | l@(y:xs') <- tails xs, ys <- f (fix (memoize . comb) l (k-1))]
memoize f = undefined -- ??
您能否就如何解决实施提出一些建议,还是我的想法完全错误?
【问题讨论】:
-
你在玩 CodeWars 吗?
-
@Arnon 是的,但这是我的扩展挑战。已经用
Data.Map写了memoization,但是很好奇如何通过定点函数来实现。 -
因为这个 kata 的解决方案非常简单,如果您以数学方式而不是编程方式处理它。我认为数学解决方案是他们的目标。它不需要任何记忆。
标签: haskell memoization