Solved day 6
This commit is contained in:
parent
9a10cf7c47
commit
98633ea9df
6 changed files with 194 additions and 1 deletions
2
file_input/day6_example_input.txt
Normal file
2
file_input/day6_example_input.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Time: 7 15 30
|
||||||
|
Distance: 9 40 200
|
|
@ -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
96
src/solutions/day6.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
2
src/solutions/day6/day_example_input.txt
Normal file
2
src/solutions/day6/day_example_input.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Time: 7 15 30
|
||||||
|
Distance: 9 40 200
|
67
src/solutions/day6/parsing.rs
Normal file
67
src/solutions/day6/parsing.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
25
src/solutions/day6/race_record.rs
Normal file
25
src/solutions/day6/race_record.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue