|
|
@ -32,8 +32,9 @@ instance Num Vector where
|
|
|
|
|
|
|
|
|
|
|
|
newtype Rope = Rope [Vector] deriving (Show, Eq)
|
|
|
|
newtype Rope = Rope [Vector] deriving (Show, Eq)
|
|
|
|
|
|
|
|
|
|
|
|
stimes :: Int -> Vector -> Vector
|
|
|
|
infix 7 .*
|
|
|
|
m `stimes` v = (fromInteger . toInteger) m * v
|
|
|
|
(.*) :: Int -> Vector -> Vector
|
|
|
|
|
|
|
|
m .* v = (fromInteger . toInteger) m * v
|
|
|
|
|
|
|
|
|
|
|
|
vlinf :: Vector -> Int
|
|
|
|
vlinf :: Vector -> Int
|
|
|
|
vlinf v = let Vector (ax, ay) = abs v in max ax ay
|
|
|
|
vlinf v = let Vector (ax, ay) = abs v in max ax ay
|
|
|
@ -45,10 +46,10 @@ newRope :: Int -> Rope
|
|
|
|
newRope l = Rope $ replicate l (Vector (0, 0))
|
|
|
|
newRope l = Rope $ replicate l (Vector (0, 0))
|
|
|
|
|
|
|
|
|
|
|
|
move :: Vector -> Char -> Int -> Vector
|
|
|
|
move :: Vector -> Char -> Int -> Vector
|
|
|
|
move v 'L' d = v + (d `stimes` (Vector (-1, 0)))
|
|
|
|
move v 'L' d = v + d .* Vector (-1, 0)
|
|
|
|
move v 'R' d = v + (d `stimes` (Vector (1, 0)))
|
|
|
|
move v 'R' d = v + d .* Vector (1, 0)
|
|
|
|
move v 'U' d = v + (d `stimes` (Vector (0, 1)))
|
|
|
|
move v 'U' d = v + d .* Vector (0, 1)
|
|
|
|
move v 'D' d = v + (d `stimes` (Vector (0, -1)))
|
|
|
|
move v 'D' d = v + d .* Vector (0, -1)
|
|
|
|
move v dir d = error $ "wrong direction:" ++ show dir
|
|
|
|
move v dir d = error $ "wrong direction:" ++ show dir
|
|
|
|
|
|
|
|
|
|
|
|
follow :: Vector -> Vector -> [Vector] -> (Vector, [Vector])
|
|
|
|
follow :: Vector -> Vector -> [Vector] -> (Vector, [Vector])
|
|
|
@ -77,9 +78,7 @@ processInput1 = length . nub . snd . foldl processLine1 (newRope 2, [Vector (0,
|
|
|
|
|
|
|
|
|
|
|
|
processLine1 :: (Rope, [Vector]) -> String -> (Rope, [Vector])
|
|
|
|
processLine1 :: (Rope, [Vector]) -> String -> (Rope, [Vector])
|
|
|
|
processLine1 (r@(Rope (h : t : [])), hist) (dir : _ : dist) =
|
|
|
|
processLine1 (r@(Rope (h : t : [])), hist) (dir : _ : dist) =
|
|
|
|
let newh = move h dir (read dist)
|
|
|
|
last . take (read dist + 1) . iterate (doStep dir) $ (r, hist)
|
|
|
|
(newt, newhist) = follow newh t hist
|
|
|
|
|
|
|
|
in (Rope [newh, newt], newhist)
|
|
|
|
|
|
|
|
processLine1 _ s = error $ "processline1 error: " ++ show s
|
|
|
|
processLine1 _ s = error $ "processline1 error: " ++ show s
|
|
|
|
|
|
|
|
|
|
|
|
processInput2 :: String -> Int
|
|
|
|
processInput2 :: String -> Int
|
|
|
@ -87,11 +86,11 @@ processInput2 = length . nub . snd . foldl processLine2 (newRope 10, [Vector (0,
|
|
|
|
|
|
|
|
|
|
|
|
processLine2 :: (Rope, [Vector]) -> String -> (Rope, [Vector])
|
|
|
|
processLine2 :: (Rope, [Vector]) -> String -> (Rope, [Vector])
|
|
|
|
processLine2 (r@(Rope (h : ks)), hist) (dir : _ : dist) =
|
|
|
|
processLine2 (r@(Rope (h : ks)), hist) (dir : _ : dist) =
|
|
|
|
last . take (read dist + 1) . iterate (move2 dir) $ (r, hist)
|
|
|
|
last . take (read dist + 1) . iterate (doStep dir) $ (r, hist)
|
|
|
|
processLine2 _ s = error $ "processline2 error: " ++ show s
|
|
|
|
processLine2 _ s = error $ "processline2 error: " ++ show s
|
|
|
|
|
|
|
|
|
|
|
|
move2 dir (r@(Rope (h : ks)), hist) =
|
|
|
|
doStep dir (r@(Rope (h : ks)), hist) =
|
|
|
|
let newh = move h dir 1
|
|
|
|
let newh = move h dir 1
|
|
|
|
(newrope, newhist) = moveRope (Rope (newh : ks)) hist
|
|
|
|
(newrope, newhist) = moveRope (Rope (newh : ks)) hist
|
|
|
|
in (newrope, newhist)
|
|
|
|
in (newrope, newhist)
|
|
|
|
move2 _ _ = error "wut"
|
|
|
|
doStep _ _ = error "wut"
|
|
|
|