81問目
http://projecteuler.net/index.php?section=problems&id=81
80 × 80 の行列を左上から右下まで、右か下にだけ移動しながら辿るとき、各点の値の合計の最小値を求める。
行列を以下のように変形する関数を作って、その結果を67問目と同じように処理しました。
1 2 3
4 5 6
7 8 9
↓
1
4 2
7 5 3
8 6
9
import Data.List main = do cs <- readFile "matrix.txt" print $ euler081 $ matrix cs matrix :: String -> [[Int]] matrix = map (read . (\ s -> "[" ++ s ++ "]")) . lines euler081 :: [[Int]] -> Int euler081 m = head $ foldl1 sum2 $ (foldl1 sum1 tri1) : tri2 where (tri1, tri2) = splitAt (length m) $ diamond m diamond :: [[Int]] -> [[Int]] diamond = map (filter (/= 0)) . transpose . diamond' where diamond' [x] = [x] diamond' (x:xs) = x : (map (0 :) $ diamond' xs) sum1 :: [Int] -> [Int] -> [Int] sum1 pre this = zipWith (+) this $ zipWith min ([head pre] ++ pre) (pre ++ [last pre]) sum2 :: [Int] -> [Int] -> [Int] sum2 pre this = zipWith (+) this $ zipWith min pre (tail pre)