From 3017e4bd43b35150cc4078dfaf30f1419bfb865c Mon Sep 17 00:00:00 2001 From: Wesley Moore Date: Tue, 11 Dec 2018 07:40:25 +1100 Subject: [PATCH] Day 4 2018 part 1 --- 2018/src/bin/day4.rs | 82 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/2018/src/bin/day4.rs b/2018/src/bin/day4.rs index f342527..bf7492f 100644 --- a/2018/src/bin/day4.rs +++ b/2018/src/bin/day4.rs @@ -3,9 +3,10 @@ extern crate lazy_static; extern crate chrono; extern crate regex; -use chrono::{DateTime, TimeZone, Utc}; +use chrono::{DateTime, TimeZone, Utc, Duration, Timelike}; use regex::Regex; use std::fs; +use std::collections::HashMap; #[derive(Debug)] enum Action { @@ -21,7 +22,7 @@ struct Entry { } fn main() { - let input = fs::read_to_string("input/2018/day4.txt").expect("input"); + let input = fs::read_to_string("input/day4.txt").expect("input"); let entries = { let mut entries = input @@ -37,9 +38,86 @@ fn main() { } 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 + 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); + + // 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(); + + println!("Day 1: {}", sleepiest_minute.0 * sleepiest_guard); +} + +fn entries_by_guard(entries: &[Entry]) -> HashMap> { + let mut entries_by_guard = HashMap::new(); + 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()); + guard_entry.push(entry); + current_guard = Some(guard_id); + } + Action::FallAsleep => { + 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 +} + +fn calculate_time_asleep(entries_by_guard: &HashMap>) -> HashMap { + let mut time_asleep = HashMap::with_capacity(entries_by_guard.len()); + + for (&guard_id, entries) in entries_by_guard { + let mut fell_asleep = None; + + for entry in entries { + match entry.action { + 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()); + *total_time_asleep = *total_time_asleep + (entry.time - fell_asleep.unwrap()); + } + } + } + } + + time_asleep +} + +fn sleep_by_minute(entries: &[&Entry]) -> HashMap { + let mut result = HashMap::new(); + let mut fell_asleep = None; + + for entry in entries { + match entry.action { + Action::BeginShift(guard_id) => {} + Action::FallAsleep => fell_asleep = Some(entry.time), + Action::WakeUp => { + for minute in fell_asleep.unwrap().minute()..entry.time.minute() { + let count_asleep = result.entry(minute).or_insert(0); + *count_asleep += 1; + } + } + } + } + + result } fn parse_entry(line: &str) -> Option {