summaryrefslogtreecommitdiff
path: root/2018/src/bin/day_4.rs
diff options
context:
space:
mode:
Diffstat (limited to '2018/src/bin/day_4.rs')
-rw-r--r--2018/src/bin/day_4.rs116
1 files changed, 116 insertions, 0 deletions
diff --git a/2018/src/bin/day_4.rs b/2018/src/bin/day_4.rs
new file mode 100644
index 0000000..2010cf8
--- /dev/null
+++ b/2018/src/bin/day_4.rs
@@ -0,0 +1,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(())
+}