From 0f862ddeac19ca08549614e86271f78b3fb64217 Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Wed, 18 Dec 2024 19:25:17 +0530 Subject: [PATCH] day 18: use binary search instead Signed-off-by: Amneesh Singh --- src/Day18.hs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Day18.hs b/src/Day18.hs index 14b5b7f..bb0b66a 100644 --- a/src/Day18.hs +++ b/src/Day18.hs @@ -1,7 +1,7 @@ module Main where import qualified AoC as A -import Data.Maybe (fromJust, isJust) +import Data.Maybe (fromJust) import qualified Data.Set as S import Text.Parsec (char, digit, many1, newline, parse, sepEndBy1) import Text.Parsec.String (Parser) @@ -28,8 +28,8 @@ 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 +dijkstra :: [Coord] -> Maybe Int +dijkstra (S.fromList -> obs) = travel (S.singleton (0, (0, 0))) S.empty where travel :: Queue -> S.Set Coord -> Maybe Int travel q vis = do @@ -47,18 +47,19 @@ dijkstra c obs = travel (S.singleton (0, c)) S.empty 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) +part1 obs = fromJust $ dijkstra (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) - ] +part2 obs = search 1025 (length obs - 1) where - n = length obs + search :: Int -> Int -> Coord + search a b + | a >= b = obs !! b + | otherwise = + let m = (a + b) `div` 2 + in case dijkstra (take m obs) of + Just _ -> search m b + Nothing -> search a (m - 1) main :: IO () main =