Done day 2 part 2
authorNeil Smith <NeilNjae@users.noreply.github.com>
Sat, 10 Dec 2022 17:41:49 +0000 (19:41 +0200)
committerNeil Smith <NeilNjae@users.noreply.github.com>
Sat, 10 Dec 2022 17:41:49 +0000 (19:41 +0200)
advent09/Main.hs

index 0f7714dad8a9bd6694671998cccd76ff95c8c991..1e23f78ead14ea5a81a5e708cb1c7dcffc2d4c62 100644 (file)
@@ -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