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