diff --git a/src/day6/mod.rs b/src/day6/mod.rs new file mode 100644 index 0000000..43f1c0b --- /dev/null +++ b/src/day6/mod.rs @@ -0,0 +1,78 @@ +use super::Part; +use log::{debug, info, trace}; +use regex::Regex; + +fn solve_race(d: u64, t: u64) -> u64 { + info!("Resolving race d={}, t={}", d, t); + let mut count = 0; + + for x in 0..t { //TODO: we could definetly do maths (erk) here but i'm in a rush + trace!("If I am holding {}ms the boat will travel {}mm/{}mm ", x, (t-x)*x, d); + if (t-x)*x > d { + trace!("Found a solution: x={}: {} * {} = {}", x, x, t-x, d); + count+=1; + } + } + + count +} + +pub fn solve(lines: Vec, part: Part) -> u64 { + let mut time_line = lines.get(0).unwrap().to_owned(); + let mut distance_line = lines.get(1).unwrap().to_owned(); + + if let Part::Two = part { + time_line.remove_matches(' '); + distance_line.remove_matches(' '); + } + + let re = Regex::new(r"\d+").unwrap(); + + let times : Vec = re.captures_iter(&time_line) + .map(|capture| capture.get(0).unwrap().as_str().parse().unwrap()) + .collect(); + debug!("Current times: {:?}", times); + + let distances : Vec = re.captures_iter(&distance_line) + .map(|capture| capture.get(0).unwrap().as_str().parse().unwrap()) + .collect(); + debug!("Current distances: {:?}", distances); + + assert_eq!(times.len(), distances.len()); + + // Holding 1 ms => +1 mm/ms + // T: total time + // d: distance + // x: number of seconds holding the button + // x * (T - x) = d + // Tx - x² = d + + let mut result = 1; + for n in 0..(times.len()) { + let t = times[n]; + let d = distances[n]; + + result *= solve_race(d, t); + } + + result +} + +#[cfg(test)] +mod tests { + use log::info; + + use crate::{day6::solve_race, utils::init_logger_test}; + fn init(){ + init_logger_test(); + } + + #[test] + fn test_solve_race() { + init(); + + assert_eq!(solve_race(9, 7), 4); + assert_eq!(solve_race(40, 15), 8); + assert_eq!(solve_race(200, 30), 9); + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index f2c4994..c13adbf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,12 @@ #![feature(let_chains)] +#![feature(string_remove_matches)] mod day1; mod day2; mod day3; mod day4; mod day5; +mod day6; mod utils; use log::info; use utils::Part; @@ -18,13 +20,8 @@ fn main() { .format_timestamp(None) .init(); - let data = utils::lines_from_file("./datasets/adventofcode.com_2023_day_5_input.txt").expect("Can't load the data"); + let data = utils::lines_from_file("./datasets/adventofcode.com_2023_day_6_input.txt").expect("Can't load the data"); //let data = utils::lines_from_file("./datasets/test.txt").expect("Can't load the data"); - let result = day5::solve(data.clone(), Part::One); - let result2 = day5::solve(data, Part::Two); - - info!("Result part 1: {}", result); - info!("Result part 2: {}", result2); } @@ -71,4 +68,13 @@ mod tests { assert_eq!(result, 20407); assert_eq!(result2, 23806951); } + + #[test] + fn day6() { + let data_path = "./datasets/adventofcode.com_2023_day_6_input.txt"; + let result = day6::solve(utils::lines_from_file(data_path).expect("Could not load the dataset for day 3"), Part::One); + let result2 = day6::solve(utils::lines_from_file(data_path).expect("Could not load the dataset for day 3"), Part::Two); + assert_eq!(result, 2612736); + assert_eq!(result2, 29891250); + } } \ No newline at end of file diff --git a/src/utils.rs b/src/utils.rs index 05b8ff3..da5a9c9 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -14,4 +14,12 @@ pub fn lines_from_file(filename: impl AsRef) -> Result> { pub enum Part { One, Two +} + +pub fn init_logger_test() { + env_logger::builder() + .filter_level(log::LevelFilter::Debug) + .format_timestamp(None) + .is_test(true) + .init(); } \ No newline at end of file