此功能是Project Euler问题解决方案的核心:
numWays tot (d:ds) = sum $ map (flip numWays ds . (tot -)) [0, d .. tot]
numWays tot []
| tot == 0 = 1
| otherwise = 0
我想相信它可以在没有显式递归的情况下重写,但递归在地图下的事实阻碍了我找到它的努力。
答案 0 :(得分:1)
import Data.List (genericLength)
numWays' tot = genericLength . filter (== 0) . foldl snoc [tot] where
snoc tots d = concatMap f tots where
f tot = map (tot -) [0, d .. tot]
我使用genericLength
代替length
,以便我的numWays'
与numWays
((Num c, Num b, Enum b) => b -> [b] -> c
)具有相同的类型。
这里的想法是,不是计算一个(零剩余总数)或零(对于非零残差总和)并对它们求和,我们将函数分解为一个递归函数,生成一个残差列表,然后(非递归地)计算该列表中有多少个零。
这样做的一点是它给我们留下了一个递归函数,我们可以更容易地从中删除递归。