-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay9.hs
54 lines (42 loc) · 1.36 KB
/
Day9.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
module Day9 (part1, part2) where
import Data.List.Split (splitOn)
import Data.Char (digitToInt)
import Data.List (nub)
import Data.Map as M (Map, fromList, (!))
import Data.Set as S (fromList, size)
import Linear (V2 (..))
day = 9
moves =
M.fromList [('R', V2 1 0), ('L', V2 (-1) 0), ('U', V2 0 (-1)), ('D', V2 0 1)]
shortRope = replicate 2 (V2 0 0)
longRope = replicate 10 (V2 0 0)
move :: V2 Int -> Char -> V2 Int
move pos c = pos + moves ! c
follow :: V2 Int -> V2 Int -> V2 Int
follow h t
| abs x < 2 && abs y < 2 = t
| otherwise = t + V2 (sig x) (sig y)
where
(V2 x y) = h - t
sig x
| x < 0 = -1
| x > 0 = 1
| x == 0 = 0
sig y
| y < 0 = -1
| y > 0 = 1
| y == 0 = 0
moveRope :: V2 Int -> [V2 Int] -> [V2 Int]
moveRope h [] = []
moveRope h (n:ns) = nn : moveRope nn ns
where
nn = follow h n
fullMove :: [V2 Int] -> Char -> [V2 Int]
fullMove (h:t) c = nh : moveRope nh t
where
nh = move h c
movements = concatMap (\(x:_:y) -> replicate (read y) x) . lines
part1 :: Bool -> String -> String
part1 _ = show . size . S.fromList . map last . scanl fullMove shortRope . movements
part2 :: Bool -> String -> String
part2 _ = show . size . S.fromList . map last . scanl fullMove longRope . movements