-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay09.hs
58 lines (52 loc) · 1.29 KB
/
Day09.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
55
56
57
58
-- |
-- Module : AOC2022.Day09
-- License : BSD3
--
-- Stability : experimental
-- Portability : non-portable
--
-- Day 9. See "AOC.Solver" for the types used in this module!
module AOC2022.Day09 (
day09a,
day09b,
)
where
import AOC.Common (listTup, strictIterate, (!!!))
import AOC.Common.Point (Dir, Point, dirPoint, parseDir)
import AOC.Solver ((:~>) (..))
import Control.Monad ((<=<))
import Data.Bitraversable (bitraverse)
import Data.List (scanl')
import Data.Maybe (listToMaybe)
import qualified Data.Set as S
import Text.Read (readMaybe)
parseLine :: String -> Maybe (Dir, Int)
parseLine =
bitraverse (parseDir <=< listToMaybe) readMaybe
<=< listTup . words
lag :: [Point] -> [Point]
lag = scanl' go 0
where
go curr new
| maximum (fmap abs dist) > 1 = curr + signum dist
| otherwise = curr
where
dist = new - curr
day09 :: Int -> [(Dir, Int)] :~> Int
day09 lagAmount =
MkSol
{ sParse = traverse parseLine . lines
, sShow = show
, sSolve =
Just
. S.size
. S.fromList
. (!!! lagAmount)
. strictIterate lag
. scanl' (+) 0
. concatMap (\(d, i) -> replicate i (dirPoint d))
}
day09a :: [(Dir, Int)] :~> Int
day09a = day09 1
day09b :: [(Dir, Int)] :~> Int
day09b = day09 9