Bits of tidying
[advent-of-code-20.git] / advent03 / src / advent03.hs
1 -- import Debug.Trace
2
3 import qualified Data.Set as S
4
5 type Position = (Int, Int)
6 type Trees = S.Set Position
7
8 main :: IO ()
9 main =
10 do text <- readFile "data/advent03.txt"
11 let (trees, maxCorner) = readGrid text
12 -- print $ trees == rg2 text
13 print $ part1 trees maxCorner
14 print $ part2 trees maxCorner
15
16
17 readGrid :: String -> (Trees, Position)
18 readGrid input = (trees, (maxR, maxC))
19 where trees = S.fromList $ concat
20 [ [(r, c) | (t, c) <- zip row [0..], t == '#']
21 | (row, r) <- zip rows [0..] ]
22 rows = lines input
23 maxC = (length $ head rows) - 1
24 maxR = (length rows) - 1
25
26 part1 trees maxCorner = countEncounteredTrees trees maxCorner (1, 3)
27
28 part2 trees maxCorner = product $ map cet [(1, 1), (1, 3), (1, 5), (1, 7), (2, 1)]
29 where cet = countEncounteredTrees trees maxCorner
30
31 countEncounteredTrees trees maxCorner delta = S.size $ S.intersection trees visited
32 where visited = S.fromList $ takeWhile (withinTrees maxCorner) $ visitedPlaces delta maxCorner
33
34 visitedPlaces :: Position -> Position -> [Position]
35 visitedPlaces (dr, dc) (_maxR, maxC) = iterate wrappingStep (0, 0)
36 where wrappingStep (r, c) = (r + dr, (c + dc) `mod` (maxC + 1))
37
38 withinTrees (maxR, maxC) (r, c) = r >= 0 && r <= maxR && c >= 0 && c <= maxC