我一直在学习一些 Haskell,并且边做边做项目 Euler 问题。我并不真正关心欧拉问题的答案(我可以很高兴地使用蛮力,或者用其他语言来解决),而是方法。
我坚持在合理的时间内完成第 15 题。它要求从 20x20 网格的左上角到右下角的非回溯路线的数量。链接在这里
我会说这个想法是记忆(sp?)函数的想法是相当明显的,但我不确定该怎么做。我用谷歌搜索,在 Haskell Cafe 上发现了这个,我天真地试图适应,但最终得到:
memRoute :: (Int,Int) -> Int
memRoute (x,y) = fromJust $ lookup (x,y) $ map (\t -> (t,route t)) [(x,y) | x <- [0..20], y <- [0..20]]
route (0,0) = 0
route (_,0) = 1
route (0,_) = 1
route (x,y) = memRoute (x-1,y) + memRoute (x,y-1)
这看起来很糟糕,并且执行得非常糟糕(比天真的版本慢很多)。问题是我并不真正了解 Haskell 记忆是如何工作的。
以我的代码为例,是否有人愿意解释a)为什么我的代码这么慢
b)应该如何完成(不使用可变变量,这是我遇到的一个解决方案)
c)在这种情况下memoization如何工作?