{- Find the maximum total from top to bottom of the triangle below. -}

import Data.Array

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]]

triArray = array ((0,0), (15,15)) $
           ([((r,c), 0) | r<-[0..15], c<-[0..15], r==0 || c==0 || r<c] ++
            [((r,c), triCalc r c) | r<-[1..15], c<-[1..r]])
triCalc r c = max (triArray!(r-1,c)) (triArray!(r-1,c-1)) + 
              tri !! (r-1) !! (c-1)

sol = maximum [(triArray!(15,n)) | n<-[1..15]]

-- Another solution from the forum; is it guaranteed to work?

 main = print ( foldr1 reduce tri ) 
     where reduce a b = zipWith ( + ) a ( zipWith max b ( tail b ) ) 

main = print (foldr1 reduce tri)
    where reduce a b = zipWith (+) a (zipWith max b (tail b))
-}
 Find the maximum total from top to bottom of the triangle below. 
 Another solution from the forum; is it guaranteed to work?

import Data.Array

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]]

triArray = array ((0,0), (15,15)) $
           ([((r,c), 0) | r<-[0..15], c<-[0..15], r==0 || c==0 || r<c] ++
            [((r,c), triCalc r c) | r<-[1..15], c<-[1..r]])
triCalc r c = max (triArray!(r-1,c)) (triArray!(r-1,c-1)) + 
              tri !! (r-1) !! (c-1)

sol = maximum [(triArray!(15,n)) | n<-[1..15]]


 main = print ( foldr1 reduce tri ) 
     where reduce a b = zipWith ( + ) a ( zipWith max b ( tail b ) ) 

main = print (foldr1 reduce tri)
    where reduce a b = zipWith (+) a (zipWith max b (tail b))
-}