-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day17.hs
63 lines (48 loc) · 1.47 KB
/
Day17.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
59
60
61
62
63
module Day17
( part1
, part2
) where
import Data.List as L (foldl')
import Data.Maybe (fromJust)
import Data.Sequence as S (Seq, index, insertAt, length, singleton)
short = [1 .. 2017]
long = [1 .. 5 * 10 ^ 7]
data State = State
{ step :: Step
, pos :: Pos
, memory :: Memory
} deriving (Show)
data QuickState = QuickState
{ qStep :: Step
, qPos :: Pos
, p1 :: Maybe Int
} deriving (Show)
type Step = Int
type Pos = Int
type Memory = Seq Int
doStep :: State -> Int -> State
doStep state p = state {pos = pos', memory = insertAt pos' p . memory $ state}
where
pos' = 1 + (pos state + step state) `mod` p
doQuickStep :: QuickState -> Int -> QuickState
doQuickStep state p
| pos' == 1 = state {qPos = pos', p1 = Just p}
| otherwise = state {qPos = pos'}
where
pos' = 1 + (qPos state + qStep state) `mod` p
initialState :: Int -> State
initialState step = State step 0 . singleton $ 0
initialQuickState :: Int -> QuickState
initialQuickState step = QuickState step 0 Nothing
nextVal :: State -> Int
nextVal (State _ curPos seq) = index seq curPos'
where
curPos' = (curPos + 1) `mod` S.length seq
part1 :: Bool -> String -> String
part1 _ input = show . nextVal . foldl' doStep state $ short
where
state = initialState . read $ input
part2 :: Bool -> String -> String
part2 _ input = show . fromJust . p1 . foldl' doQuickStep quickState $ long
where
quickState = initialQuickState . read $ input