Ryan is an engineer in the Sacramento Area with a focus in Python, Ruby, and Rust. Bash/Python Exercism mentor. Coding, physics, calculus, music, woodworking. Looking for work!
Done! Completed my solution with just minutes to spare before the next day goes live! I thought I would like this challenge. I did not. It was fine, for the most part. But I spent at least fifteen minutes wondering why my solution wasn't working before I realized the #!@%#@!$! LOGS WERE NOT IN CHRONOLOGICAL ORDER.
Let me tell you: I was not calm in that moment.
After I used VS Code's built-in sorting functionality to pre-sort the input text, it was mostly smooth sailing. However, rust gurus, before I sorted my input, every time I ran cargo run, the output would be a different answer, even with no changes to the code. Anybody know why that might be? I would expect a static input file and static code to make the same result every time.
Anyways.
Part 1
usestd::collections::HashMap;/// Day 4: Repose Record/// /// Track the sleeping times of various security guards// Part 1: Find the guard who slept most and their most-slept minute/// The security team (made up of a bunch of Guards) that we're monitoringstructSecurityTeam{guards:HashMap<usize,Guard>,}implSecurityTeam{pubfnnew()->Self{Self{guards:HashMap::new()}}/// Loads in a log-file-like schedule from text/// /// Entries have the form '[YYYY-MM-DD HH:MM] message'/// Possible messages are 'Guard #<id> begins shift'/// 'falls asleep'/// 'wakes up'/// Assumes that the logs are in chronological order (WHICH IS SANE)pubfnload_schedule(&mutself,text:&str){letmutcurrent_guard=0;letmutcurrent_state="";letmutsleep_start=0;forlineintext.lines(){// Yeah I'm hard-coding the minutes location, DON'T JUDGE MEletminute:usize=line[15..17].parse().expect("Minutes weren't a number");letaction=&line[19..];ifaction.contains("Guard"){// New guard starting shift.letid=action.trim_matches(|c:char|!c.is_numeric()).parse().expect("No guard ID");self.guards.entry(id).or_insert(Guard::new(id));current_guard=id;current_state="awake";}elseifaction.contains("falls asleep"){// Ignores double-falls asleepifcurrent_state=="awake"{current_state="asleep";sleep_start=minute;}}elseifaction.contains("wakes up"){// Ignores double-wakesifcurrent_state=="asleep"{self.guards.get_mut(¤t_guard).unwrap().track_sleep(sleep_start,minute);current_state="awake";}}}}/// Returns the guard with the overall most minutes asleeppubfnsleepiest_guard(&self)->&Guard{self.guards.values().max_by_key(|guard|guard.total_minutes_asleep()).expect("No guards on team")}}/// A security guard. He keeps track of his own sleep times (what a great person)!structGuard{id:usize,sleep_minutes:HashMap<usize,usize>,}implGuard{pubfnnew(id:usize)->Self{Self{id,sleep_minutes:HashMap::new()}}pubfnid(&self)->usize{self.id}/// Returns the minute in which this guard most commonly slept/// /// Accounts for the possibility that this guard doesn't suck at their/// job and stays awake the whole time.pubfnsleepiest_minute(&self)->usize{*self.sleep_minutes.iter().max_by_key(|(_id,minutes)|**minutes).unwrap_or((&0,&0)).0}/// Sums up this guards total sleeping timepubfntotal_minutes_asleep(&self)->usize{self.sleep_minutes.values().sum()}/// Logs in a length of time where the guard was asleeppubfntrack_sleep(&mutself,asleep:usize,awake:usize){forminuteinasleep..awake{*self.sleep_minutes.entry(minute).or_insert(0)+=1}}}/// Part 1 asks for the ID of the guard who slept the most multiplied by/// the minute they slept mostpubfnpart1(text:&str)->usize{letmutguards=SecurityTeam::new();guards.load_schedule(text);letsleepy=guards.sleepiest_guard();sleepy.id()*sleepy.sleepiest_minute()}
Part 2
Part 2 went pretty quick now that I've got all this infrastructure in place.
// Part 2implSecurityTeam{/// Returns the guard that fell asleep the most on the same minutepubfnmost_consistent_sleeper(&self)->&Guard{self.guards.values().max_by_key(|guard|guard.sleep_on(guard.sleepiest_minute())).expect("No guards on team")}}implGuard{/// Returns the amount of times this guard slept on a given minutepubfnsleep_on(&self,minute:usize)->usize{*self.sleep_minutes.get(&minute).unwrap_or(&0)}}/// Part two asks for the ID of the guard who slept the most on a single/// minute multiplied by that minutepubfnpart2(text:&str)->usize{letmutguards=SecurityTeam::new();guards.load_schedule(text);letconsistent_guard=guards.most_consistent_sleeper();consistent_guard.id()*consistent_guard.sleepiest_minute()}
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Done! Completed my solution with just minutes to spare before the next day goes live! I thought I would like this challenge. I did not. It was fine, for the most part. But I spent at least fifteen minutes wondering why my solution wasn't working before I realized the #!@%#@!$! LOGS WERE NOT IN CHRONOLOGICAL ORDER.
Let me tell you: I was not calm in that moment.
After I used VS Code's built-in sorting functionality to pre-sort the input text, it was mostly smooth sailing. However, rust gurus, before I sorted my input, every time I ran
cargo run
, the output would be a different answer, even with no changes to the code. Anybody know why that might be? I would expect a static input file and static code to make the same result every time.Anyways.
Part 1
Part 2
Part 2 went pretty quick now that I've got all this infrastructure in place.