2022-12-09 08:02:19 +01:00
import Data.List
2022-12-11 12:03:12 +01:00
import Linear.V2
2022-12-09 08:02:19 +01:00
2022-12-11 12:03:12 +01:00
type Rope = ( V2 Int , V2 Int )
2022-12-09 08:02:19 +01:00
main :: IO ()
main = do
2022-12-11 12:03:12 +01:00
input <- concatMap ( parse . words ) . lines <$> readFile " input "
2022-12-10 05:58:58 +01:00
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
2022-12-11 12:03:12 +01:00
where
field =
concatMap nub $
group $ reverse $ snd $ moveAll ( ( V2 0 0 , V2 0 0 ) , [] ) input
2022-12-09 08:02:19 +01:00
parse :: [ String ] -> [ V2 Int ]
2022-12-11 12:03:12 +01:00
parse [ dir , len ]
2022-12-09 08:02:19 +01:00
| dir == " R " = f $ V2 1 0
| dir == " L " = f $ V2 ( - 1 ) 0
| dir == " U " = f $ V2 0 1
| dir == " D " = f $ V2 0 ( - 1 )
2022-12-11 12:03:12 +01:00
where
f = replicate ( read len )
2022-12-09 08:02:19 +01:00
2022-12-11 12:03:12 +01:00
moveAll :: ( Rope , [ V2 Int ] ) -> [ V2 Int ] -> ( Rope , [ V2 Int ] )
2022-12-09 08:02:19 +01:00
moveAll r ( x : xs ) = moveAll ( move r x ) xs
2022-12-11 12:03:12 +01:00
moveAll ( ( head , tail ) , xs ) _ = ( ( head , tail ) , tail : xs )
2022-12-09 08:02:19 +01:00
2022-12-11 12:03:12 +01:00
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
2022-12-09 08:02:19 +01:00
2022-12-11 12:03:12 +01:00
tailMove :: V2 Int -> V2 Int
2022-12-09 08:02:19 +01:00
tailMove ( V2 a b ) = V2 ( f a ) ( f b )
2022-12-11 12:03:12 +01:00
where
f x
| abs x == 2 = signum x
| abs a + abs b <= 2 = 0
| otherwise = x