-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day4.fsx
106 lines (101 loc) · 3.99 KB
/
Day4.fsx
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//PART 1
let input = @"[1518-11-01 00:00] Guard #10 begins shift
[1518-11-01 00:05] falls asleep
[1518-11-01 00:25] wakes up
[1518-11-01 00:30] falls asleep
[1518-11-01 00:55] wakes up
[1518-11-01 23:58] Guard #99 begins shift
[1518-11-02 00:40] falls asleep
[1518-11-02 00:50] wakes up
[1518-11-03 00:05] Guard #10 begins shift
[1518-11-03 00:24] falls asleep
[1518-11-03 00:29] wakes up
[1518-11-04 00:02] Guard #99 begins shift
[1518-11-04 00:36] falls asleep
[1518-11-04 00:46] wakes up
[1518-11-05 00:03] Guard #99 begins shift
[1518-11-05 00:45] falls asleep
[1518-11-05 00:55] wakes up
"
open System.Text.RegularExpressions
type Action =
| Sleep of int
| Wake of int
| BeginShift of int
static member Parse (s:string) =
match s.Substring(19, 4) with
| "Guar" -> BeginShift(Regex.Match(s.Substring(19), @"(\d+)").Value |> int)
| "wake" -> Wake(Regex.Match(s.Substring(15,2), @"(\d+)").Value |> int)
| "fall" -> Sleep(Regex.Match(s.Substring(15,2), @"(\d+)").Value |> int)
| _ -> failwith ("Parse error: " + s)
input.Split([|'\n';'\r'|], System.StringSplitOptions.RemoveEmptyEntries)
|> Array.sort
|> Array.map Action.Parse
|> Array.fold (fun (map,id,start) action ->
match action with
| BeginShift(guard) ->
if Map.containsKey guard map then
map, guard, 0
else
Map.add guard [] map, guard, 0
| Sleep(sleeptime) -> map, id, sleeptime
| Wake(waketime) ->
Map.add id ([start .. (waketime - 1)] @ Map.find id map) map, id, 0
) (Map.empty,0,0)
|> (fun (map,_,_) -> map)
|> Map.toArray
|> Array.sortByDescending (fun (k,v) -> List.length v)
|> Array.item 0
|> (fun (k,v) -> k, v |> List.groupBy id |> List.sortByDescending (fun (_, l) -> List.length l) |> List.item 0)
|> (fun (guard,(k,v)) -> guard * k)
//PART 2
let input = @"[1518-11-01 00:00] Guard #10 begins shift
[1518-11-01 00:05] falls asleep
[1518-11-01 00:25] wakes up
[1518-11-01 00:30] falls asleep
[1518-11-01 00:55] wakes up
[1518-11-01 23:58] Guard #99 begins shift
[1518-11-02 00:40] falls asleep
[1518-11-02 00:50] wakes up
[1518-11-03 00:05] Guard #10 begins shift
[1518-11-03 00:24] falls asleep
[1518-11-03 00:29] wakes up
[1518-11-04 00:02] Guard #99 begins shift
[1518-11-04 00:36] falls asleep
[1518-11-04 00:46] wakes up
[1518-11-05 00:03] Guard #99 begins shift
[1518-11-05 00:45] falls asleep
[1518-11-05 00:55] wakes up
"
open System.Text.RegularExpressions
type Action =
| Sleep of int
| Wake of int
| BeginShift of int
static member Parse (s:string) =
match s.Substring(19, 4) with
| "Guar" -> BeginShift(Regex.Match(s.Substring(19), @"(\d+)").Value |> int)
| "wake" -> Wake(Regex.Match(s.Substring(15,2), @"(\d+)").Value |> int)
| "fall" -> Sleep(Regex.Match(s.Substring(15,2), @"(\d+)").Value |> int)
| _ -> failwith ("Parse error: " + s)
input.Split([|'\n';'\r'|], System.StringSplitOptions.RemoveEmptyEntries)
|> Array.sort
|> Array.map Action.Parse
|> Array.fold (fun (map,id,start) action ->
match action with
| BeginShift(guard) ->
if Map.containsKey guard map then
map, guard, 0
else
Map.add guard [] map, guard, 0
| Sleep(sleeptime) -> map, id, sleeptime
| Wake(waketime) ->
Map.add id ([start .. (waketime - 1)] @ Map.find id map) map, id, 0
) (Map.empty,0,0)
|> (fun (map,_,_) -> map)
|> Map.toArray
|> Array.filter (fun (guard, minutes) -> (List.length minutes) > 0)
|> Array.map (fun (guard,minutes) -> guard, minutes |> List.groupBy id |> List.map (fun (minute,instances) -> minute, List.length instances) |> List.sortByDescending snd |> List.item 0)
|> Array.sortByDescending (fun (guard,(minute,length)) -> length)
|> Array.item 0
|> (fun (guard,(minute,length)) -> guard * minute)