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
107
108
109
110
111
112
113
114
115
116
|
extern crate advent_of_code_2018;
use advent_of_code_2018::*;
use std::str::FromStr;
use std::error::Error;
use std::path::PathBuf;
use std::collections::HashMap;
// cargo watch -cs "cargo run --release --bin day_4"
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
struct Event {
date: String,
hour: u32,
minute: u32,
what: EventType
}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
enum EventType {
BeginShift(u32),
Asleep,
Awake
}
impl FromStr for Event {
type Err = Box<Error>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let date = s.split_whitespace().nth(0).unwrap().trim_matches('[').to_string();
let time = s.split_whitespace().nth(1).unwrap().trim_matches(']');
let hour = time.split(':').nth(0).unwrap().parse().unwrap();
let minute = time.split(':').nth(1).unwrap().parse().unwrap();
let guard = s.split_whitespace().nth(3).and_then(|x| x.trim_matches('#').parse().ok());
let what = match s.split_whitespace().nth(2).unwrap() {
"Guard" => EventType::BeginShift(guard.unwrap()),
"falls" => EventType::Asleep,
"wakes" => EventType::Awake,
_ => panic!("Unknown event")
};
Ok(Event {
date,
hour,
minute,
what
})
}
}
#[derive(Debug)]
struct GuardSleepStats {
per_minute: HashMap<u32, u32>
}
impl GuardSleepStats {
fn new() -> GuardSleepStats {
GuardSleepStats {
per_minute: HashMap::new()
}
}
fn total(&self) -> u32 {
self.per_minute.values().sum()
}
}
fn main() -> Result<(), Box<Error>> {
let input = read_file(&PathBuf::from("inputs/4.txt"))?;
//println!("Input: {:?}", input);
let mut events: Vec<Event> = input.iter().map(|line| line.parse().unwrap()).collect();
events.sort();
//println!("Events: {:?}", events);
let mut sleep = HashMap::new();
let mut current_guard = 0;
let mut last_asleep = 0;
for event in events {
match event.what {
EventType::BeginShift(guard) => current_guard = guard,
EventType::Asleep => last_asleep = event.minute,
EventType::Awake => {
for i in last_asleep..event.minute {
*sleep
.entry(current_guard)
.or_insert(GuardSleepStats::new())
.per_minute
.entry(i)
.or_insert(0) += 1
}
}
}
}
println!("Stats: {:?}", sleep);
let (sleepiest_guard, sleepiest_stats) = sleep.iter().max_by_key(|(_,v)| v.total()).unwrap().clone();
println!("Sleepiest guard: {:?}", sleepiest_guard);
let (sleepiest_minute, sleepiest_occurances) = sleepiest_stats.per_minute.iter().max_by_key(|(_,v)| *v).unwrap().clone();
println!("Sleepiest minute: {:?}", sleepiest_minute);
println!("Part 1 answer: {}", sleepiest_guard * sleepiest_minute);
let (specific_minute_offender, specific_minute_stats) = sleep.iter().max_by_key(|(_,v)| v.per_minute.values().max().unwrap()).unwrap().clone();
println!("Specific minute: {:?}", specific_minute_offender);
let (specific_minute_minute, specific_minute_occurances) = specific_minute_stats.per_minute.iter().max_by_key(|(_,v)| *v).unwrap().clone();
println!("Specific Minute minute: {:?}", specific_minute_minute);
println!("Part 2 answer: {}", specific_minute_offender * specific_minute_minute);
Ok(())
}
|