Life Goes On

まあまあだけど楽しんでる方です

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)