Project Euler Problem 18

http://projecteuler.net/index.php?section=problems&id=18
以下の三角形の頂点から底辺までの和の最大値(移動ルートは直下の左右のみ)


75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23

以下の単純な例で考える


01
03 02
04 05 06
10 09 08 07
まず1段目を2段目に足す

04 03
04 05 06
10 09 08 07
2段目(2つの選択肢の内大きい方)を3段目に足す

08 09 09
10 09 08 07
3段目を4段目に足す

18 18 17 16
たぶんこれの最大値が求めるもの

tri = [[75],
       [95,64],
       [17,47,82],
       [18,35,87,10],
       [20,04,82,47,65],
       [19,01,23,75,03,34],
       [88,02,77,73,07,63,67],
       [99,65,04,28,06,16,70,92],
       [41,41,26,56,83,40,80,70,33],
       [41,48,72,33,47,32,37,16,94,29],
       [53,71,44,65,25,43,91,52,97,51,14],
       [70,11,33,28,77,73,17,78,39,68,17,57],
       [91,71,52,38,17,14,91,43,58,50,27,29,48],
       [63,66,04,68,89,53,67,30,73,16,69,87,40,31],
       [04,62,98,27,23,09,70,98,73,93,38,53,60,04,23]]

main = print $ maximum $ foldl1 euler18 tri

euler18 :: [Int] -> [Int] -> [Int]
euler18 li1 li2 = euler18' li1 li2 0
                  where euler18' li1 li2 x
                         | x == 0                = [(li2 !! 0) + (li1 !! 0)] ++ euler18' li1 li2 (x+1)
                         | x == (length li2) - 1 = [(li2 !! x) + (li1 !! (x-1))]
                         | otherwise             = [(li2 !! x) + maximum[(li1 !! x), (li1 !! (x-1))]] ++ euler18' li1 li2 (x+1)