day04 both
This commit is contained in:
149
src/tasks/day04.rs
Normal file
149
src/tasks/day04.rs
Normal file
@@ -0,0 +1,149 @@
|
||||
use chrono::prelude::*;
|
||||
use chrono::Duration;
|
||||
use chrono::NaiveDateTime;
|
||||
use std::collections::HashMap;
|
||||
use 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);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod day01;
|
||||
pub mod day02;
|
||||
pub mod day03;
|
||||
pub mod day04;
|
||||
|
||||
Reference in New Issue
Block a user