During last three days I have been trying to solve Project Euler 15 in Haskell.
Here is my current state:
import Data.Map as Map
data Coord = Coord Int Int deriving (Show, Ord, Eq)
corner :: Coord -> Bool
corner (Coord x y) = (x == 0) && (y == 0)
side :: Coord -> Bool
side (Coord x y) = (x == 0) || (y == 0)
move_right :: Coord -> Coord
move_right (Coord x y) = Coord (x - 1) y
move_down :: Coord -> Coord
move_down (Coord x y) = Coord x (y - 1)
calculation :: Coord -> Integer
calculation coord
| corner coord = 0
| side coord = 1
| otherwise = (calculation (move_right coord)) + (calculation (move_down coord))
problem_15 :: Int -> Integer
problem_15 size =
calculation (Coord size size)
It works fine but it is very slow if the ‘n’ is getting bigger.
As I know I can use the dynamic programming and the hashtable (Data.Map, for example) to cache calculated values.
I was trying to use memoization, but don’t have a success. I was trying to use Data.Map, but each next error was more scary then previous. So I ask your help: how to cache values which was already calculated ?
I know about mathematical solution of this problem (Pascal triangle), but I am interested in the algorithmic solution.
Instead of a Map, this problem is better suited for an two-dimensional array cache, since we have a bounded range for input values.
We add
deriving Ixto Coord so we can use it directly as an array index and in calculation, we initialize a two-dimensional arraycachewith the lower bound ofCoord 0 0and upper bound ofcoord. Then instead of recursively callingcalculationwe just refer to the values in the cache.Now we can calculate even large values relatively quickly.
*Main> problem_15 1000
2048151626989489714335162502980825044396424887981397033820382637671748186202083755828932994182610206201464766319998023692415481798004524792018047549769261578563012896634320647148511523952516512277685886115395462561479073786684641544445336176137700738556738145896300713065104559595144798887462063687185145518285511731662762536637730846829322553890497438594814317550307837964443708100851637248274627914170166198837648408435414308177859470377465651884755146807496946749238030331018187232980096685674585602525499101181135253534658887941966653674904511306110096311906270342502293155911108976733963991149120