-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathday04.rs
More file actions
49 lines (41 loc) · 1.46 KB
/
Copy pathday04.rs
File metadata and controls
49 lines (41 loc) · 1.46 KB
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
//! # Repose Record
use crate::util::hash::*;
use crate::util::parse::*;
type Input = FastMap<usize, [u32; 60]>;
pub fn parse(input: &str) -> Input {
// Records need to be in chronological order.
let mut records: Vec<_> = input.lines().collect();
records.sort_unstable();
// Build each sleep schedule.
let mut id = 0;
let mut start = 0;
let mut guards = FastMap::new();
for record in records {
match record.len() {
31 => start = record[15..17].unsigned(),
27 => {
let end = record[15..17].unsigned();
let minutes = guards.entry(id).or_insert_with(|| [0; 60]);
(start..end).for_each(|i| minutes[i] += 1);
}
_ => id = record[26..record.len() - 13].unsigned(),
}
}
guards
}
/// Find the guard with the greatest total minutes asleep.
pub fn part1(input: &Input) -> usize {
choose(input, |m| m.iter().sum())
}
/// Find the guard with the highest single minute asleep.
pub fn part2(input: &Input) -> usize {
choose(input, |m| *m.iter().max().unwrap())
}
fn choose(input: &Input, strategy: impl Fn(&[u32; 60]) -> u32) -> usize {
// Find the guard using a specific strategy.
let (id, minutes) = input.iter().max_by_key(|(_, m)| strategy(m)).unwrap();
// Find the minute spent asleep the most.
let (minute, _) = minutes.iter().enumerate().max_by_key(|&(_, &m)| m).unwrap();
// Return the result.
id * minute
}