83問目
http://projecteuler.net/index.php?section=problems&id=83
80 × 80 の行列を左上から右下まで、上下左右に移動しながら辿るとき、各点の値の合計の最小値を求める。
次に進むべき点が分からないので、これまで通った点の近傍を進むべき点の候補としてリストに保持し、そのうち合計値が最小になるところから選んで進んでいきます。
import Data.List main = do s <- readFile "matrix.txt" print $ euler083 $ matrix s matrix :: String -> [[Int]] matrix = map (read . (\ s -> "[" ++ s ++ "]")) . lines euler083 :: [[Int]] -> Int euler083 val = fst $ head $ dropWhile ((/= (m, m)) . snd) $ map (head . fst) $ iterate search ([(val !! 0 !! 0, (0, 0))], []) where search (a : as, bs) = (sort $ as ++ arround a (map snd $ as ++ bs), a : bs) arround (i, (x0, y0)) zs = [ (i + (val !! x !! y), (x, y)) | (x, y) <- [(x0, y0-1), (x0, y0+1), (x0-1, y0), (x0+1, y0)] \\ zs, x >= 0, x <= m, y >= 0, y <= m ] m = length val - 1