AoC/2022/day09/day09.hs
2022-12-11 12:03:12 +01:00

46 lines
1.1 KiB
Haskell

import Data.List
import Linear.V2
type Rope = (V2 Int, V2 Int)
main :: IO ()
main = do
input <- concatMap (parse . words) . lines <$> readFile "input"
print $ length $ nub $ day9 1 input
print $ length $ nub $ day9 9 input
day9 :: Int -> [V2 Int] -> [V2 Int]
day9 n input
| n > 1 = day9 (pred n) (zipWith (-) (tail field) field)
| otherwise = field
where
field =
concatMap nub $
group $ reverse $ snd $ moveAll ((V2 0 0, V2 0 0), []) input
parse :: [String] -> [V2 Int]
parse [dir, len]
| dir == "R" = f $ V2 1 0
| dir == "L" = f $ V2 (-1) 0
| dir == "U" = f $ V2 0 1
| dir == "D" = f $ V2 0 (-1)
where
f = replicate (read len)
moveAll :: (Rope, [V2 Int]) -> [V2 Int] -> (Rope, [V2 Int])
moveAll r (x:xs) = moveAll (move r x) xs
moveAll ((head, tail), xs) _ = ((head, tail), tail : xs)
move :: (Rope, [V2 Int]) -> V2 Int -> (Rope, [V2 Int])
move ((head, tail), ps) m = ((head + m, newTail), tail : ps)
where
newTail = tailMove (head + m - tail) + tail
tailMove :: V2 Int -> V2 Int
tailMove (V2 a b) = V2 (f a) (f b)
where
f x
| abs x == 2 = signum x
| abs a + abs b <= 2 = 0
| otherwise = x