Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
2024-12-18 11:17:17 +05:30
parent 54f512a51f
commit aedfc5a7f4
2 changed files with 77 additions and 0 deletions

View File

@@ -135,3 +135,9 @@ executable day17
hs-source-dirs: src
main-is: Day17.hs
build-depends: libaoc
executable day18
import: common
hs-source-dirs: src
main-is: Day18.hs
build-depends: libaoc, containers

71
src/Day18.hs Normal file
View File

@@ -0,0 +1,71 @@
module Main where
import qualified AoC as A
import Data.Maybe (fromJust, isJust)
import qualified Data.Set as S
import Text.Parsec (char, digit, many1, newline, parse, sepEndBy1)
import Text.Parsec.String (Parser)
type Coord = (Int, Int)
type Queue = S.Set (Int, Coord)
parseBytes :: Parser [Coord]
parseBytes =
( (,)
<$> (read <$> many1 digit)
<*> (char ',' >> (read <$> many1 digit))
)
`sepEndBy1` newline
width :: Int
height :: Int
(width, height) = (71, 71)
oob :: Coord -> Bool
oob (x, y) = x < 0 || x >= width || y < 0 || y >= height
neighbours :: Coord -> [Coord]
neighbours (x, y) = [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]
dijkstra :: Coord -> S.Set Coord -> Maybe Int
dijkstra c obs = travel (S.singleton (0, c)) S.empty
where
travel :: Queue -> S.Set Coord -> Maybe Int
travel q vis = do
((dis, c), q') <- S.minView q
let ns = neighbours c
q'' = foldr S.insert q' . map (dis + 1,) . filter (not . invalid) $ ns
vis' = S.insert c vis
if c == (width - 1, height - 1)
then Just dis
else travel q'' vis'
where
invalid :: Coord -> Bool
invalid c = c `S.member` vis || c `S.member` obs || oob c
part1 :: [Coord] -> Int
part1 obs = fromJust $ dijkstra (0, 0) (S.fromList . take 1024 $ obs)
part2 :: [Coord] -> Coord
part2 obs =
(!!) obs $
head
[ i
| i <- [n, n - 1 .. 1],
isJust $ dijkstra (0, 0) (S.fromList $ take i obs)
]
where
n = length obs
main :: IO ()
main =
do
raw <- readFile "./inputs/day18.in"
let bytes = A.extract $ parse parseBytes "" raw
putStr "Part 1: " >> print (part1 bytes)
putStr "Part 2: " >> print (part2 bytes)