1
1
mirror of https://github.com/theoludwig/advent_of_code.git synced 2025-05-18 19:27:51 +02:00

chore: simplify structure + multiple years of advent of code possible

This commit is contained in:
2025-02-20 08:59:13 +01:00
parent 31bcb54699
commit f34d6208bd
84 changed files with 305 additions and 3186 deletions

View File

@ -0,0 +1,114 @@
use rayon::prelude::*;
#[derive(Debug, Default, PartialEq, Clone)]
pub struct Race {
pub maximum_time_in_milliseconds: usize,
pub best_distance_in_millimeters_recorded: usize,
}
impl Race {
pub fn get_all_winning_strategies(&self) -> Vec<RaceStrategy> {
(1..self.maximum_time_in_milliseconds)
.into_par_iter()
.map(|time_in_milliseconds_holding_button| RaceStrategy {
time_in_milliseconds_holding_button,
maximum_time_in_milliseconds: self.maximum_time_in_milliseconds,
})
.filter(|race_strategy| {
let distance_in_millimeters_travelled =
race_strategy.calculate_distance_in_millimeters_travelled();
distance_in_millimeters_travelled > self.best_distance_in_millimeters_recorded
})
.collect::<Vec<RaceStrategy>>()
}
}
#[derive(Debug, Default, PartialEq, Clone)]
pub struct RaceStrategy {
pub time_in_milliseconds_holding_button: usize,
pub maximum_time_in_milliseconds: usize,
}
impl RaceStrategy {
pub fn calculate_distance_in_millimeters_travelled(&self) -> usize {
(self.maximum_time_in_milliseconds - self.time_in_milliseconds_holding_button)
* self.time_in_milliseconds_holding_button
}
}
pub fn part_1(input: &str) -> usize {
fn get_numbers_from_line(line: &str) -> Vec<usize> {
line.split(':')
.last()
.unwrap_or_default()
.split_ascii_whitespace()
.map(|value| value.trim())
.filter(|value| !value.is_empty())
.map(|value| {
let result: usize = value.parse().unwrap_or_default();
result
})
.collect::<Vec<usize>>()
}
let mut lines = input.trim().lines();
let maximum_times = get_numbers_from_line(lines.next().unwrap_or_default());
let best_distances = get_numbers_from_line(lines.next().unwrap_or_default());
maximum_times
.iter()
.zip(best_distances.iter())
.map(
|(&maximum_time_in_milliseconds, &best_distance_recorded_in_millimeters)| Race {
maximum_time_in_milliseconds,
best_distance_in_millimeters_recorded: best_distance_recorded_in_millimeters,
},
)
.map(|race| race.get_all_winning_strategies().len())
.product()
}
pub fn part_2(input: &str) -> usize {
fn get_number_from_line(line: &str) -> usize {
line.split(':')
.last()
.unwrap_or_default()
.replace(' ', "")
.trim()
.parse()
.unwrap_or_default()
}
let mut lines = input.trim().lines();
let race = Race {
maximum_time_in_milliseconds: get_number_from_line(lines.next().unwrap_or_default()),
best_distance_in_millimeters_recorded: get_number_from_line(
lines.next().unwrap_or_default(),
),
};
race.get_all_winning_strategies().len()
}
#[cfg(test)]
mod puzzle_2023_day_6_tests {
use super::*;
#[test]
fn test_part_1_example() {
assert_eq!(part_1(include_str!("../input_example_1.txt")), 288);
}
#[test]
fn test_part_2_example() {
assert_eq!(part_2(include_str!("../input_example_1.txt")), 71503);
}
#[test]
fn test_part_1() {
assert_eq!(part_1(include_str!("../input.txt")), 1083852);
}
#[test]
fn test_part_2() {
assert_eq!(part_2(include_str!("../input.txt")), 23501589);
}
}

View File

@ -0,0 +1,8 @@
use puzzle_2023_day_6::{part_1, part_2};
fn main() {
let input = include_str!("../input.txt");
println!("- Day 6 of 2023: Wait For It -");
println!("Answer Part 1: {}", part_1(input));
println!("Answer Part 2: {}", part_2(input));
}