-
Notifications
You must be signed in to change notification settings - Fork 0
/
day1.hs
41 lines (34 loc) · 1.23 KB
/
day1.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
import Data.Complex
import Data.List
import Data.Maybe
direction :: Char -> Complex Float
direction 'L' = 0 :+ 1
direction 'R' = 0 :+ (-1)
blocks :: String -> Float
blocks str =
let [(count, _)] = reads str
in count
parse :: String -> [(Complex Float, Float)]
parse = map (\(x:xs) -> (direction x, blocks xs)) . words
advance :: (Complex Float, Complex Float) -> (Complex Float, Float) -> (Complex Float, Complex Float)
advance (dir, pos) (turn, steps) =
let dir' = dir * turn
pos' = pos + dir' * (steps :+ 0)
in (dir', pos')
part1 :: String -> Int
part1 input =
let parts = parse input
(_, (x :+ y)) = foldl advance (0 :+ 1, 0 :+ 0) parts
in grid x + grid y
where grid = round . abs
firstTwice :: (Complex Float, Complex Float) -> [(Complex Float, Float)] -> [Complex Float] -> Complex Float
firstTwice (dir, pos) (x:xs) prev =
let (turn, steps) = x
(dir':_, poss@(pos':_)) = unzip $ map (advance (dir, pos)) $ map (\s -> (turn, s)) $ reverse [1..steps]
in fromMaybe (firstTwice (dir', pos') xs (poss ++ prev)) (listToMaybe $ intersect poss prev)
part2 :: String -> Int
part2 input =
let parts = parse input
(x :+ y) = firstTwice (0 :+ 1, 0 :+ 0) parts []
in grid x + grid y
where grid = round . abs