Solved day 6

This commit is contained in:
BoolPurist 2024-08-18 15:03:45 +02:00
parent 9a10cf7c47
commit 98633ea9df
6 changed files with 194 additions and 1 deletions

View file

@ -0,0 +1,2 @@
Time: 7 15 30
Distance: 9 40 200

View file

@ -1,4 +1,5 @@
pub mod day5; pub mod day5;
pub mod day6;
pub fn create_solutions() -> Vec<Vec<fn(&str) -> String>> { pub fn create_solutions() -> Vec<Vec<fn(&str) -> String>> {
vec![ vec![
@ -7,7 +8,7 @@ pub fn create_solutions() -> Vec<Vec<fn(&str) -> String>> {
vec![not_implemented_yet, not_implemented_yet], vec![not_implemented_yet, not_implemented_yet],
vec![not_implemented_yet, not_implemented_yet], vec![not_implemented_yet, not_implemented_yet],
vec![day5::solve_task_1, day5::solve_task_2], vec![day5::solve_task_1, day5::solve_task_2],
vec![not_implemented_yet, not_implemented_yet], vec![day6::solve_task_1, day6::solve_task_2],
vec![not_implemented_yet, not_implemented_yet], vec![not_implemented_yet, not_implemented_yet],
vec![not_implemented_yet, not_implemented_yet], vec![not_implemented_yet, not_implemented_yet],
vec![not_implemented_yet, not_implemented_yet], vec![not_implemented_yet, not_implemented_yet],

96
src/solutions/day6.rs Normal file
View file

@ -0,0 +1,96 @@
mod parsing;
mod race_record;
type NumericValue = u64;
pub fn solve_task_1(input: &str) -> String {
let parsed = parsing::parsing(input);
let mut how_many_times_won = 1;
for next_record in parsed {
how_many_times_won *= all_rounds_of_durations(next_record.time())
.into_iter()
.filter(|&distance| distance > next_record.reached_distance())
.count() as NumericValue;
}
how_many_times_won.to_string()
}
pub fn solve_task_2(input: &str) -> String {
let parsed = parsing::parsing_part_2(input);
let how_many_times_won = all_rounds_of_durations(parsed.time())
.into_iter()
.filter(|&distance| distance > parsed.reached_distance())
.count() as NumericValue;
how_many_times_won.to_string()
}
fn all_rounds_of_durations(duration: NumericValue) -> Vec<NumericValue> {
std::iter::repeat(duration)
.take(duration as usize)
.enumerate()
.map(|(speed_duration, duration)| {
simuluate_reached_distance_at(duration, speed_duration as NumericValue)
})
.collect()
}
fn simuluate_reached_distance_at(
duration: NumericValue,
speed_duration: NumericValue,
) -> NumericValue {
assert!(duration >= speed_duration);
let rest_time = duration - speed_duration;
rest_time * speed_duration
}
#[cfg(test)]
mod testing {
use crate::solutions::day6::{simuluate_reached_distance_at, solve_task_2, NumericValue};
use super::solve_task_1;
#[test]
fn should_simuluate_reached_distance_at() {
fn assert_case(
duration: NumericValue,
speed_duration: NumericValue,
expected: NumericValue,
) {
let actual = simuluate_reached_distance_at(duration, speed_duration);
assert_eq!(
expected, actual,
"Duration: {}\n Speed Duration: {}",
duration, speed_duration
);
}
const DURATION: NumericValue = 7;
for (speed_duration, expected) in [
(0, 0),
(1, 6),
(2, 10),
(3, 12),
(4, 12),
(5, 10),
(6, 6),
(7, 0),
] {
assert_case(DURATION, speed_duration, expected)
}
}
#[test]
fn should_solve_task_1() {
let input = include_str!("day6/day_example_input.txt");
let actual = solve_task_1(input);
let expected = "288";
assert_eq!(expected, actual);
}
#[test]
fn should_solve_task_2() {
let input = include_str!("day6/day_example_input.txt");
let actual = solve_task_2(input);
let expected = "71503";
assert_eq!(expected, actual);
}
}

View file

@ -0,0 +1,2 @@
Time: 7 15 30
Distance: 9 40 200

View file

@ -0,0 +1,67 @@
use super::{race_record::RaceRecord, NumericValue};
pub fn parsing(input: &str) -> Vec<RaceRecord> {
let mut must_be_2_lines = input.lines().take(2);
match (must_be_2_lines.next(), must_be_2_lines.next()) {
(Some(first_line), Some(second_line)) => {
let stripped_first = first_line.strip_prefix("Time:").unwrap();
let stripped_second = second_line.strip_prefix("Distance:").unwrap();
let splitted_first = stripped_first
.split_whitespace()
.map(|to_parse| to_parse.parse::<NumericValue>().unwrap());
let splitted_second = stripped_second
.split_whitespace()
.map(|to_parse| to_parse.parse::<NumericValue>().unwrap());
splitted_first
.zip(splitted_second)
.map(|(time, distance)| RaceRecord::new(time, distance))
.collect()
}
_ => unreachable!(),
}
}
pub fn parsing_part_2(input: &str) -> RaceRecord {
let (time_str, reached_str) = parsing(input)
.into_iter()
.map(|record| {
(
record.time().to_string(),
record.reached_distance().to_string(),
)
})
.fold(
(String::new(), String::new()),
|(acc_time_str, acc_reached_str), (time_str, distance_str)| {
(acc_time_str + &time_str, acc_reached_str + &distance_str)
},
);
RaceRecord::new(time_str.parse().unwrap(), reached_str.parse().unwrap())
}
#[cfg(test)]
mod testing {
use crate::solutions::day6::race_record::RaceRecord;
#[test]
fn should_parse() {
let input = include_str!("day_example_input.txt");
let parsed = super::parsing(input);
let expected = vec![
RaceRecord::new(7, 9),
RaceRecord::new(15, 40),
RaceRecord::new(30, 200),
];
assert_eq!(expected, parsed);
}
#[test]
fn should_parse_part_2() {
let input = include_str!("day_example_input.txt");
let parsed = super::parsing_part_2(input);
let expected = RaceRecord::new(71530, 940200);
assert_eq!(expected, parsed);
}
}

View file

@ -0,0 +1,25 @@
use derive_more::derive::Debug;
use super::NumericValue;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct RaceRecord {
time: NumericValue,
reached_distance: NumericValue,
}
impl RaceRecord {
pub fn new(time: NumericValue, reached_distance: NumericValue) -> Self {
Self {
time,
reached_distance,
}
}
pub fn time(&self) -> NumericValue {
self.time
}
pub fn reached_distance(&self) -> NumericValue {
self.reached_distance
}
}