From: Neil Smith Date: Sat, 10 Dec 2022 17:41:49 +0000 (+0200) Subject: Done day 2 part 2 X-Git-Url: https://git.njae.me.uk/?a=commitdiff_plain;h=af51352432524d04dbbd302bb2c239a2ea600b72;p=advent-of-code-22.git Done day 2 part 2 --- diff --git a/advent09/Main.hs b/advent09/Main.hs index 0f7714d..1e23f78 100644 --- a/advent09/Main.hs +++ b/advent09/Main.hs @@ -1,4 +1,4 @@ --- Writeup at https://work.njae.me.uk/2022/12/04/advent-of-code-2022-day-4/ +-- Writeup at https://work.njae.me.uk/2022/12/10/advent-of-code-2022-day-9/ import AoC import Data.Text (Text) @@ -15,8 +15,8 @@ type Trace = S.Set Position type Path = [Position] data Rope = Rope - { _headR :: Position - , _tailR :: Position + { _headK :: Position + , _knots :: [Position] , _trace :: Trace } deriving (Show, Eq) makeLenses ''Rope @@ -31,10 +31,15 @@ main = let path = successfulParse text let steps = expandPath path print $ part1 steps + print $ part2 steps part1 :: Path -> Int part1 steps = S.size $ rope' ^. trace - where rope' = ropeSteps newRope steps + where rope' = ropeSteps (newRope 1) steps + +part2 steps = S.size $ rope' ^. trace + where rope' = ropeSteps (newRope 9) steps + expandPath :: [Direction] -> Path expandPath = concatMap expandStep @@ -54,21 +59,28 @@ touching p1 p2 = (manhattan p1 p2) <= 1 towards :: Position -> Position -> Position towards p1 p2 = signum $ p2 ^-^ p1 -newRope :: Rope -newRope = Rope { _headR = V2 0 0, _tailR = V2 0 0, _trace = S.singleton (V2 0 0) } +newRope :: Int -> Rope +newRope n = Rope { _headK = V2 0 0, _knots = replicate n (V2 0 0), _trace = S.singleton (V2 0 0) } ropeSteps :: Rope -> Path -> Rope ropeSteps rope steps = foldl' ropeStep rope steps ropeStep :: Rope -> Position -> Rope -ropeStep rope step = rope & headR .~ hr - & tailR .~ tailR' - & trace %~ S.insert tailR' - where hr = (rope ^. headR) ^+^ step - tr = rope ^. tailR - tailR' = if tr `touching` hr - then rope ^. tailR - else tr ^+^ (tr `towards` hr) +ropeStep rope step = rope & headK .~ h + & knots .~ (reverse kts') + & trace %~ S.insert (head kts') + where h = (rope ^. headK) ^+^ step + kts = rope ^. knots + (_, kts') = foldl' knotStep (h, []) kts + + +-- foldl' (f) (hr, []) knots + +knotStep (h, ks) kt = (kt', (kt':ks)) + where kt' = if kt `touching` h + then kt + else kt ^+^ (kt `towards` h) + -- Parse the input file