aboutsummaryrefslogtreecommitdiff
path: root/2020/03b.hs
blob: 43e7ba243a2b6cf3570a0482c807c5d5d874b502 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
module Day3 where

import System.Environment (getArgs)

data Square = Empty | Tree
    deriving (Eq, Ord, Show)

type Map = [[Square]]

-- Converts lines to a map
toMap :: [String] -> Map
toMap = map toRow
        where toRow = map toSquare
              toSquare '.' = Empty
              toSquare '#' = Tree
              toSquare _ = error "Invalid map character"

-- Get the size of a map
-- Note this returns (height, width)
getSize :: Map -> (Int, Int)
getSize m = (length m, length (head m))

-- Get the square at the given (y, x) coord
-- This wraps the x coord, but not the y
get :: Map -> Int -> Int -> Square
get m y x = m!!y!!(x `mod` w)
              where (_, w) = getSize m

-- Get the squares encountered along a slop, starting at (y, x)
-- and descending along (f, r)
getSquaresAlongSlope :: Map -> Int -> Int -> Int -> Int -> [Square]
getSquaresAlongSlope m y x f r | y >= h = []
                               | otherwise = get m y x : getSquaresAlongSlope m (y + f) (x + r) f r
                                    where (h, _) = getSize m

-- Count the number of trees along a given slope, starting at (0, 0)
checkSlope :: Map -> Int -> Int -> Int
checkSlope m f r = length $ filter (== Tree) $ getSquaresAlongSlope m 0 0 f r

-- Usage: ./3b inputs/day3
main :: IO ()
main = do
        args <- getArgs;
        content <- readFile $ head args;
        let l = lines content;
        let m = toMap l;
        print $ product $ map (uncurry $ checkSlope m) [(1, 1), (1, 3), (1, 5), (1, 7), (2, 1)]
        return ()