mirror of
https://github.com/wezm/advent-of-code.git
synced 2024-12-18 10:19:55 +00:00
Add day 4 2018 part 2
This commit is contained in:
parent
3017e4bd43
commit
bf93a2b8ae
1 changed files with 83 additions and 24 deletions
|
@ -3,10 +3,10 @@ extern crate lazy_static;
|
|||
extern crate chrono;
|
||||
extern crate regex;
|
||||
|
||||
use chrono::{DateTime, TimeZone, Utc, Duration, Timelike};
|
||||
use chrono::{DateTime, Duration, TimeZone, Timelike, Utc};
|
||||
use regex::Regex;
|
||||
use std::fs;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Action {
|
||||
|
@ -21,6 +21,14 @@ struct Entry {
|
|||
action: Action,
|
||||
}
|
||||
|
||||
impl Entry {
|
||||
fn new(time: DateTime<Utc>, action: Action) -> Self {
|
||||
Self { time, action }
|
||||
}
|
||||
}
|
||||
|
||||
// If anyone is reading this, it's not great Rust code...
|
||||
|
||||
fn main() {
|
||||
let input = fs::read_to_string("input/day4.txt").expect("input");
|
||||
|
||||
|
@ -33,25 +41,66 @@ fn main() {
|
|||
entries.sort_unstable_by(|a, b| a.time.cmp(&b.time));
|
||||
entries
|
||||
};
|
||||
let entries_by_guard = entries_by_guard(&entries);
|
||||
|
||||
part1(&entries);
|
||||
part1(&entries_by_guard);
|
||||
part2(&entries_by_guard);
|
||||
}
|
||||
|
||||
fn part1(entries: &[Entry]) {
|
||||
// First group entries by guard
|
||||
let entries_by_guard = entries_by_guard(entries);
|
||||
|
||||
// Next find the one that was asleep the most
|
||||
fn part1(entries_by_guard: &HashMap<u32, Vec<&Entry>>) {
|
||||
// Find the one that was asleep the most
|
||||
let guards_by_time_asleep = calculate_time_asleep(&entries_by_guard);
|
||||
let asleep_the_most = guards_by_time_asleep.iter().max_by(|(_guard_id, time_asleep), (_other_guard_id, other_time_asleep)| time_asleep.cmp(other_time_asleep));
|
||||
println!("{:?}", asleep_the_most);
|
||||
let asleep_the_most = guards_by_time_asleep.iter().max_by(
|
||||
|(_guard_id, time_asleep), (_other_guard_id, other_time_asleep)| {
|
||||
time_asleep.cmp(other_time_asleep)
|
||||
},
|
||||
);
|
||||
|
||||
// Now find the minute that guard is asleep the most
|
||||
let sleepiest_guard = asleep_the_most.unwrap().0;
|
||||
let sleep_by_minute = sleep_by_minute(&entries_by_guard[sleepiest_guard]);
|
||||
let sleepiest_minute = sleep_by_minute.iter().max_by(|(_minute, count), (_other_minute, other_count)| count.cmp(other_count)).unwrap();
|
||||
let sleepiest_minute = sleep_by_minute
|
||||
.iter()
|
||||
.max_by(|(_minute, count), (_other_minute, other_count)| count.cmp(other_count))
|
||||
.unwrap();
|
||||
|
||||
println!("Day 1: {}", sleepiest_minute.0 * sleepiest_guard);
|
||||
println!("Part 1: {}", sleepiest_minute.0 * sleepiest_guard);
|
||||
}
|
||||
|
||||
fn part2(entries_by_guard: &HashMap<u32, Vec<&Entry>>) {
|
||||
let results: HashMap<_, _> = entries_by_guard
|
||||
.keys()
|
||||
.filter_map(|guard_id| {
|
||||
let sleep_by_minute = sleep_by_minute(&entries_by_guard[&guard_id]);
|
||||
|
||||
if sleep_by_minute.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some((guard_id, sleep_by_minute))
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Now find the answer
|
||||
if let Some((guard_id, minute_counts)) =
|
||||
results
|
||||
.iter()
|
||||
.max_by(|(_, minute_counts), (_, other_minute_counts)| {
|
||||
max_minute(&minute_counts)
|
||||
.1
|
||||
.cmp(&max_minute(&other_minute_counts).1)
|
||||
})
|
||||
{
|
||||
let minute = max_minute(minute_counts).0;
|
||||
println!(
|
||||
"Part 2: guard {} * minute {} = {}",
|
||||
*guard_id,
|
||||
minute,
|
||||
*guard_id * minute
|
||||
);
|
||||
} else {
|
||||
println!("Part 2: No result found");
|
||||
}
|
||||
}
|
||||
|
||||
fn entries_by_guard(entries: &[Entry]) -> HashMap<u32, Vec<&Entry>> {
|
||||
|
@ -59,19 +108,25 @@ fn entries_by_guard(entries: &[Entry]) -> HashMap<u32, Vec<&Entry>> {
|
|||
let mut current_guard = None;
|
||||
|
||||
for entry in entries {
|
||||
println!("{:?}", entry);
|
||||
|
||||
match entry.action {
|
||||
Action::BeginShift(guard_id) => {
|
||||
let guard_entry = entries_by_guard.entry(guard_id).or_insert_with(|| Vec::new());
|
||||
let guard_entry = entries_by_guard
|
||||
.entry(guard_id)
|
||||
.or_insert_with(|| Vec::new());
|
||||
guard_entry.push(entry);
|
||||
current_guard = Some(guard_id);
|
||||
}
|
||||
Action::FallAsleep => {
|
||||
entries_by_guard.get_mut(¤t_guard.unwrap()).unwrap().push(entry);
|
||||
entries_by_guard
|
||||
.get_mut(¤t_guard.unwrap())
|
||||
.unwrap()
|
||||
.push(entry);
|
||||
}
|
||||
Action::WakeUp => {
|
||||
entries_by_guard.get_mut(¤t_guard.unwrap()).unwrap().push(entry);
|
||||
entries_by_guard
|
||||
.get_mut(¤t_guard.unwrap())
|
||||
.unwrap()
|
||||
.push(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,10 +142,12 @@ fn calculate_time_asleep(entries_by_guard: &HashMap<u32, Vec<&Entry>>) -> HashMa
|
|||
|
||||
for entry in entries {
|
||||
match entry.action {
|
||||
Action::BeginShift(guard_id) => {}
|
||||
Action::BeginShift(_guard_id) => {}
|
||||
Action::FallAsleep => fell_asleep = Some(entry.time),
|
||||
Action::WakeUp => {
|
||||
let total_time_asleep = time_asleep.entry(guard_id).or_insert_with(|| Duration::zero());
|
||||
let total_time_asleep = time_asleep
|
||||
.entry(guard_id)
|
||||
.or_insert_with(|| Duration::zero());
|
||||
*total_time_asleep = *total_time_asleep + (entry.time - fell_asleep.unwrap());
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +163,7 @@ fn sleep_by_minute(entries: &[&Entry]) -> HashMap<u32, u32> {
|
|||
|
||||
for entry in entries {
|
||||
match entry.action {
|
||||
Action::BeginShift(guard_id) => {}
|
||||
Action::BeginShift(_guard_id) => {}
|
||||
Action::FallAsleep => fell_asleep = Some(entry.time),
|
||||
Action::WakeUp => {
|
||||
for minute in fell_asleep.unwrap().minute()..entry.time.minute() {
|
||||
|
@ -141,8 +198,10 @@ fn parse_entry(line: &str) -> Option<Entry> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Entry {
|
||||
fn new(time: DateTime<Utc>, action: Action) -> Self {
|
||||
Self { time, action }
|
||||
}
|
||||
fn max_minute(hash: &HashMap<u32, u32>) -> (u32, u32) {
|
||||
hash
|
||||
.iter()
|
||||
.max_by(|(_, count), (_, other_count)| count.cmp(other_count))
|
||||
.map(|(&minute, &count)| (minute, count))
|
||||
.unwrap()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue