Files
aoc_2018/src/tasks/day04.rs
Johannes Schaefer cd16a42821 push to edition 2018
2018-12-07 09:53:18 +01:00

150 lines
4.5 KiB
Rust

use chrono::prelude::*;
use chrono::Duration;
use chrono::NaiveDateTime;
use std::collections::HashMap;
use crate::utils;
enum Activity {
Starts(u32),
FallsAsleep,
Awakens,
}
#[derive(PartialEq)]
enum State {
Asleep,
Awake,
}
pub fn task1() {
use self::Activity::*;
let input = utils::read_file("input/day04.txt");
let mut input: Vec<_> = input
.lines()
.map(|line| {
// [1518-10-26 00:01] Guard #1069 begins shift
let time = NaiveDateTime::parse_from_str(&line[1..=16], "%Y-%m-%d %H:%M").unwrap();
let activity = if line.contains("falls asleep") {
Activity::FallsAsleep
} else if line.contains("wakes up") {
Activity::Awakens
} else {
let number: u32 = line.split(' ').find(|part| part.starts_with("#")).unwrap()[1..]
.parse()
.unwrap();
Activity::Starts(number)
};
(time, activity)
}).collect();
input.sort_by_key(|it| it.0);
let mut current_id: u32 = 0;
let mut current_state = State::Awake;
let mut last_time = input[0].0;
let mut sleep_map: HashMap<u32, [usize; 60]> = HashMap::new();
let minute = Duration::minutes(1);
for (time, activity) in input.into_iter() {
// for all minutes since last time slot fill arrays
let mut iter_time = last_time.clone();
while iter_time < time {
if current_state == State::Asleep && iter_time.hour() == 0 {
sleep_map.entry(current_id).or_insert([0; 60])[iter_time.minute() as usize] += 1;
}
iter_time += minute;
}
match activity {
Starts(id) => {
current_state = State::Awake;
current_id = id;
}
FallsAsleep => current_state = State::Asleep,
Awakens => current_state = State::Awake,
}
last_time = time;
}
let sleeper = sleep_map
.iter()
.map(|(id, schedule)| (id, schedule.iter().sum::<usize>()))
.max_by_key(|it| it.1)
.unwrap();
println!("Sleeper: {:?}", sleeper);
let worst_minute = sleep_map
.get(sleeper.0)
.unwrap()
.iter()
.enumerate()
.max_by_key(|it| it.1)
.unwrap()
.0;
println!("Worst minute: {}", worst_minute);
println!("Result: {}", *sleeper.0 as usize * worst_minute);
}
pub fn task2() {
use self::Activity::*;
let input = utils::read_file("input/day04.txt");
let mut input: Vec<_> = input
.lines()
.map(|line| {
// [1518-10-26 00:01] Guard #1069 begins shift
let time = NaiveDateTime::parse_from_str(&line[1..=16], "%Y-%m-%d %H:%M").unwrap();
let activity = if line.contains("falls asleep") {
Activity::FallsAsleep
} else if line.contains("wakes up") {
Activity::Awakens
} else {
let number: u32 = line.split(' ').find(|part| part.starts_with("#")).unwrap()[1..]
.parse()
.unwrap();
Activity::Starts(number)
};
(time, activity)
}).collect();
input.sort_by_key(|it| it.0);
let mut current_id: u32 = 0;
let mut current_state = State::Awake;
let mut last_time = input[0].0;
let mut sleep_map: HashMap<u32, [usize; 60]> = HashMap::new();
let minute = Duration::minutes(1);
for (time, activity) in input.into_iter() {
// for all minutes since last time slot fill arrays
let mut iter_time = last_time.clone();
while iter_time < time {
if current_state == State::Asleep && iter_time.hour() == 0 {
sleep_map.entry(current_id).or_insert([0; 60])[iter_time.minute() as usize] += 1;
}
iter_time += minute;
}
match activity {
Starts(id) => {
current_state = State::Awake;
current_id = id;
}
FallsAsleep => current_state = State::Asleep,
Awakens => current_state = State::Awake,
}
last_time = time;
}
let sleeper = sleep_map
.iter()
.max_by_key(|(_, array)| array.iter().max())
.unwrap();
let worst_minute = sleeper
.1
.iter()
.enumerate()
.max_by_key(|it| it.1)
.unwrap()
.0;
println!("Result 2: {}", *sleeper.0 as usize * worst_minute);
}