-
Notifications
You must be signed in to change notification settings - Fork 0
/
4a.hs
58 lines (50 loc) · 1.55 KB
/
4a.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
import qualified Data.Map as M
import Data.List (foldl', sort)
import Debug.Trace
{-
[1518-03-18 23:50] Guard #2591 begins shift
[1518-10-30 00:48] falls asleep
[1518-07-14 00:40] wakes up
-}
{-
Wrong: 23776 too high
-}
data Event =
Shift Integer
| Wake Integer
| Sleep Integer
main = interact (
show
. findMax . sched M.empty
. map parseLine
. sort . lines
)
parseLine :: String -> Event
parseLine = (
fun
. words . filter (/=']') . filter (/='#')
. drop 15 -- drop until minutes
)
fun (min:one:two:_) = case one of
"Guard" -> Shift (read two)
"falls" -> Sleep (read min)
"wakes" -> Wake (read min)
sched m (Shift guard:xs) = schedShift guard m 0 xs
sched m [] = m
schedShift _ m _ [] = sched m []
schedShift guard m prev xs@(Shift _:_) = sched m xs
schedShift guard m prev (Sleep now:xs) = schedShift guard m now xs
schedShift guard m prev (Wake now:xs) =
let m2 = foldl' (\m1 i -> M.insertWith (+) (guard,i) 1 m1) m [prev..(now-1)]
in schedShift guard m2 now xs
findMax :: M.Map (Integer,Integer) Integer -> Integer
findMax guardmin2nr =
let
guard2nr = M.foldrWithKey' (\(guard,_) nr -> M.insertWith (+) guard nr) M.empty guardmin2nr
(_,lazyGuard) = M.foldrWithKey' (\guard nr -> max (nr,guard)) (-1,-1) guard2nr
min2nr =
M.mapKeys (\(guard,min) -> min)
. M.filterWithKey (\(guard,min) _ -> lazyGuard == guard)
$ guardmin2nr
(_,lazyMin) = M.foldrWithKey' (\min nr -> max (nr,min)) (-1,-1) min2nr
in lazyGuard*lazyMin