From 1ba0fa56eb6e515a0a089ba56bfcdfcd5a826605 Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Sun, 15 Dec 2024 23:41:11 +0530 Subject: [PATCH] day 15 Signed-off-by: Amneesh Singh --- aoc2024.cabal | 6 +++++ src/Day15.hs | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 src/Day15.hs diff --git a/aoc2024.cabal b/aoc2024.cabal index fe78c44..818cb67 100644 --- a/aoc2024.cabal +++ b/aoc2024.cabal @@ -116,3 +116,9 @@ executable day14 build-depends: , containers , libaoc + +executable day15 + import: common + hs-source-dirs: src + main-is: Day15.hs + build-depends: containers diff --git a/src/Day15.hs b/src/Day15.hs new file mode 100644 index 0000000..c5fd5d1 --- /dev/null +++ b/src/Day15.hs @@ -0,0 +1,75 @@ +module Main where + +import qualified Data.Map as M + +type Coord = (Int, Int) + +type Grid = M.Map Coord Char + +data Dir = East | West | North | South deriving (Eq) + +next :: Coord -> Dir -> Coord +next (x, y) East = (x + 1, y) +next (x, y) West = (x - 1, y) +next (x, y) North = (x, y - 1) +next (x, y) South = (x, y + 1) + +dir :: Char -> Dir +dir '>' = East +dir '<' = West +dir '^' = North +dir 'v' = South + +widen :: Char -> [Char] +widen '#' = "##" +widen 'O' = "[]" +widen '.' = ".." +widen '@' = "@." + +parse :: [[Char]] -> (Coord, Grid) +parse raw = + let [bot] = [(x, y) | (y, row) <- zip [0 ..] raw, (x, ch) <- zip [0 ..] row, ch == '@'] + raw' = [((x, y), ch) | (y, row) <- zip [0 ..] raw, (x, ch) <- zip [0 ..] row] + grid = M.insert bot '.' $ M.fromList raw' + in (bot, grid) + +move :: [Dir] -> Coord -> Grid -> Grid +move [] _ grid = grid +move (d : ds) c grid = case move' c d grid of + Nothing -> move ds c grid + Just grid' -> move ds (next c d) grid' + where + move' :: Coord -> Dir -> Grid -> Maybe Grid + move' c d grid = case M.lookup n grid of + Just '.' -> Just grid + Just '#' -> Nothing + Just 'O' -> push n d <$> move' n d grid + Just '[' | d `elem` [East, West] -> push n d <$> move' n d grid + Just '[' -> push n d . push r d <$> (move' n d grid >>= move' r d) + Just ']' | d `elem` [East, West] -> push n d <$> move' n d grid + Just ']' -> push n d . push l d <$> (move' n d grid >>= move' l d) + _ -> error "what?" + where + n :: Coord + n@(x, y) = next c d + r = (x + 1, y) + l = (x - 1, y) + + push :: Coord -> Dir -> Grid -> Grid + push c d grid = case M.lookup c grid of + Just ch -> M.insert (next c d) ch $ M.insert c '.' grid + Nothing -> error "what?" + +gps :: Grid -> Char -> Int +gps grid char = sum [y * 100 + x | ((x, y), ch) <- M.assocs grid, ch == char] + +main :: IO () +main = + do + (raw, map dir . concat -> moves) <- break null . lines <$> readFile "./inputs/day15.in" + + let (bot1, grid1) = parse raw + (bot2, grid2) = parse . map (concatMap widen) $ raw + + putStr "Part 1: " >> print (gps (move moves bot1 grid1) 'O') + putStr "Part 2: " >> print (gps (move moves bot2 grid2) '[')