Skip to content

Instantly share code, notes, and snippets.

@mkeeter
Created December 4, 2018 12:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mkeeter/0d455d30f1195f67805953a54f19652f to your computer and use it in GitHub Desktop.
Save mkeeter/0d455d30f1195f67805953a54f19652f to your computer and use it in GitHub Desktop.
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