Created
December 4, 2018 12:47
-
-
Save mkeeter/0d455d30f1195f67805953a54f19652f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::str::FromStr; | |
#[macro_use] extern crate nom; | |
use nom::types::CompleteByteSlice; | |
#[macro_use] extern crate itertools; | |
use std::collections::HashMap; | |
/* | |
[1518-11-01 00:00] Guard #10 begins shift | |
[1518-11-01 00:05] falls asleep | |
[1518-11-01 00:25] wakes up | |
*/ | |
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] | |
struct Event { | |
year: usize, | |
month: usize, | |
day: usize, | |
hour: usize, | |
minute: usize, | |
action: Action, | |
} | |
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] | |
enum Action { | |
Begin(usize), | |
Sleep, | |
Wake, | |
} | |
named!(usize_<CompleteByteSlice, usize>, | |
map_res!(recognize!(nom::digit), |s:CompleteByteSlice| | |
usize::from_str(std::str::from_utf8(s.0).unwrap()))); | |
named!(action<CompleteByteSlice, Action>, | |
alt!(value!(Action::Sleep, tag!("falls asleep")) | | |
value!(Action::Wake, tag!("wakes up")) | | |
do_parse!(tag!("Guard #") >> id: usize_ >> tag!(" begins shift") | |
>> (Action::Begin(id))))); | |
named!(parse_line<CompleteByteSlice, Event>, | |
do_parse!(tag!("[") >> | |
year: usize_ >> | |
tag!("-") >> | |
month: usize_ >> | |
tag!("-") >> | |
day: usize_ >> | |
tag!(" ") >> | |
hour: usize_ >> | |
tag!(":") >> | |
minute: usize_ >> | |
tag!("] ") >> action: action >> | |
(Event { year: year, month: month, day: day, hour: hour, minute: minute, action: action}))); | |
named!(parse_lines<CompleteByteSlice, Vec<Event>>, | |
many0!(do_parse!( p: parse_line >> tag!("\n") >> (p)))); | |
fn part1() { | |
let input = include_bytes!("../input"); | |
let mut events: Vec<Event> = parse_lines(CompleteByteSlice(input)).unwrap().1; | |
events.sort(); | |
let mut sleeping = HashMap::new(); | |
{ | |
let mut guard = None; | |
let mut sleep = None; | |
for e in events.iter() { | |
match e.action { | |
Action::Begin(id) => guard = Some(id), | |
Action::Wake => *sleeping.entry(guard.unwrap()).or_insert(0) += e.minute - sleep.unwrap(), | |
Action::Sleep => sleep = Some(e.minute), | |
} | |
} | |
} | |
let mut most_sleep = 0; | |
let mut sleepiest_guard = 0; | |
for (guard, sleep) in sleeping.iter() { | |
if *sleep > most_sleep { | |
sleepiest_guard = *guard; | |
most_sleep = *sleep; | |
} | |
} | |
println!("Got sleepiest guard {:?} with {:?}", sleepiest_guard, most_sleep); | |
let mut mins = [0; 60]; | |
{ | |
let mut guard = None; | |
let mut sleep = None; | |
for e in events.iter() { | |
match e.action { | |
Action::Begin(id) => guard = Some(id), | |
Action::Wake => | |
if guard == Some(sleepiest_guard) { | |
for i in sleep.unwrap()..e.minute { | |
mins[i] += 1; | |
} | |
}, | |
Action::Sleep => sleep = Some(e.minute), | |
} | |
} | |
} | |
let mut most_sleep = 0; | |
for i in 0..60 { | |
print!("{} ", mins[i]); | |
if mins[i] > mins[most_sleep] { | |
most_sleep = i | |
} | |
} | |
println!("Got sleepiest minute {}", most_sleep); | |
println!("Answer to part 1: {}", most_sleep * sleepiest_guard); | |
} | |
fn main() { | |
let input = include_bytes!("../input"); | |
let mut events: Vec<Event> = parse_lines(CompleteByteSlice(input)).unwrap().1; | |
events.sort(); | |
let mut sleeping = HashMap::new(); | |
{ | |
let mut guard = None; | |
let mut sleep = None; | |
for e in events.iter() { | |
match e.action { | |
Action::Begin(id) => guard = Some(id), | |
Action::Wake => { | |
let minutes = sleeping.entry(guard.unwrap()).or_insert([0; 60]); | |
for i in sleep.unwrap()..e.minute { | |
minutes[i] += 1; | |
} | |
}, | |
Action::Sleep => sleep = Some(e.minute), | |
} | |
} | |
} | |
let mut most_sleep = 0; | |
let mut sleepiest_guard = 0; | |
let mut sleepiest_minute = 0; | |
for i in 0..60 { | |
for (guard, mins) in sleeping.iter() { | |
if mins[i] > most_sleep { | |
most_sleep = mins[i]; | |
sleepiest_guard = *guard; | |
sleepiest_minute = i; | |
} | |
} | |
} | |
println!("Got sleepiest guard {}, minute {}, product {}", sleepiest_guard, | |
sleepiest_minute, sleepiest_guard * sleepiest_minute); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment