Project Euler #11: Largest product in a grid

  • + 0 comments

    Haskell. Not pretty

    import Control.Applicative
    import Control.Monad
    import System.IO
    import Data.List
    
    down_check :: [[Int]] -> Int -> Int -> Int -> Int
    right_check :: [[Int]] -> Int -> Int -> Int -> Int
    diag_check :: [[Int]] -> Int -> Int -> Int -> Int
    ldiag_check :: [[Int]] -> Int -> Int -> Int 
    rdiag_check :: [[Int]] -> Int -> Int -> Int 
    
    down_check gridL max x y
        | x > 16 = max
        | y > 19 = down_check gridL max (x+1) 0
        | product [gridL !! x !! y, gridL !! (x+1) !! y, 
                   gridL !! (x+2) !! y, gridL !! (x+3) !! y] 
          > max = 
                down_check 
                    gridL 
                    (product [gridL !! x !! y, gridL !! (x+1) !! y, 
                              gridL !! (x+2) !! y, gridL !! (x+3) !! y]) 
                    x (y+1)
        | otherwise = down_check gridL max x (y+1)
    
    right_check gridL max x y
        | x > 19 = max
        | y > 16 = right_check gridL max (x+1) 0
        | product [gridL !! x !! y, gridL !! x !! (y+1), 
                   gridL !! x !! (y+2), gridL !! x !! (y+3)] 
          > max = 
                right_check 
                    gridL 
                    (product [gridL !! x !! y, gridL !! x !! (y+1), 
                              gridL !! x !! (y+2), gridL !! x !! (y+3)]) 
                    x (y+1)
        | otherwise = right_check gridL max x (y+1)
        
    diag_check gridL max x y
        | x > 16 = max
        | y > 19 = diag_check gridL max (x+1) 0
        | maximum [ldiag_check gridL x y, rdiag_check gridL x y] > max = 
                diag_check 
                    gridL 
                    (maximum [ldiag_check gridL x y, rdiag_check gridL x y]) 
                    x 
                    (y+1)
        | otherwise = diag_check gridL max x (y+1)
        
    ldiag_check gridL x 0 = 0
    ldiag_check gridL x 1 = 0
    ldiag_check gridL x 2 = 0
    ldiag_check gridL x 3 = 0
    ldiag_check gridL x y = product [gridL !! x !! y, gridL !! (x+1) !! (y-1),
                                     gridL !! (x+2) !! (y-2), gridL !! (x+3) !! (y-3)]
    
    rdiag_check gridL x 16 = 0
    rdiag_check gridL x 17 = 0
    rdiag_check gridL x 18 = 0
    rdiag_check gridL x 19 = 0
    rdiag_check gridL x y = product [gridL !! x !! y, gridL !! (x+1) !! (y+1),
                                     gridL !! (x+2) !! (y+2), gridL !! (x+3) !! (y+3)]
    
    main :: IO ()
    main = do
        grid_temp <- getMultipleLines 20
        let grid = map ( map ( read :: String -> Int ) . words ) grid_temp
        let down_max = down_check grid 0 0 0
        let right_max = right_check grid 0 0 0
        let diag_max = diag_check grid 0 0 0
        print (maximum [down_max, right_max, diag_max])
    
    getMultipleLines :: Int -> IO [String]
    
    getMultipleLines n
        | n <= 0 = return []
        | otherwise = do          
            x <- getLine         
            xs <- getMultipleLines (n-1)    
            let ret = (x:xs)    
            return ret