From a583d00fd920cd1ae75279e5b456dc1a03835851 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 3 Dec 2023 14:05:21 +0100 Subject: [PATCH] Day03 - part 1 --- src/day03.rs | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 2 + 2 files changed, 120 insertions(+) create mode 100644 src/day03.rs diff --git a/src/day03.rs b/src/day03.rs new file mode 100644 index 0000000..12a9b0f --- /dev/null +++ b/src/day03.rs @@ -0,0 +1,118 @@ +use std::io::Read; +use std::error::Error; +use std::fs::File; + +use regex::Regex; + +pub fn run(input_file: &str) -> Result<(), Box> { + let mut f = File::open(input_file)?; + let mut input = String::new(); + f.read_to_string(&mut input)?; + + let res = run_part1(&input)?; + println!("{res}"); + + let res = run_part2(&input)?; + println!("{res}"); + + Ok(()) +} + +fn run_part1(input: &str) -> Result> { + println!("Running day03 - part 1"); + + // faire une première passe à la recherche de l'index de chaque symbole + // pour chaque ligne stocker true/false à chaque index + // au final on a un vecteur de ligne qui contient un vecteur de bool + // indiquant la présence ou non d'un symbole à l'index + let mut symbols: Vec> = Vec::new(); + input.lines() + .for_each(|l| { + let mut symbol: Vec = Vec::new(); + l.chars() + .for_each(|c| symbol.push(c != '.' && !c.is_ascii_digit())); + symbols.push(symbol); + }); + //println!("{:?}", symbols); + + // seconde passe où les nombres sont extraits ainsi que les index de début + // et de fin + // puis recherche d'un symbole adjacent + // si un symbole est trouvé, on ajoute le nombre au résultat + let re = Regex::new(r"\d+").unwrap(); + + fn is_next_to_symbol(line_number: usize, idx_start: usize, idx_end: usize, symbols: &Vec>) -> bool { + let n_lines = symbols.len() - 1; // 0-based value + let n_cols = symbols[0].len() - 1; // 0-based value + let start = if idx_start > 0 { idx_start - 1 } else { 0 }; + let end = if idx_end < n_cols { idx_end + 1 } else { n_cols }; + + for i in start..end { + if line_number > 0 { + if symbols[line_number - 1][i] { + return true; + } + } + if line_number < n_lines { + if symbols[line_number + 1][i] { + return true; + } + } + if symbols[line_number][i] { + return true; + } + } + + false + } + + let mut res = 0; + input.lines().enumerate() + .for_each(|(idx, l)| { + re.captures_iter(l) + .for_each(|c| { + //println!("{idx}: {:?}", c); + let m = c.get(0).unwrap(); + if is_next_to_symbol(idx, m.start(), m.end(), &symbols) { + res += m.as_str().parse::().unwrap(); + } + }) + }); + + Ok(res) +} + +fn run_part2(input: &str) -> Result> { + println!("Running day03 - part 2"); + let res = 0; + Ok(res) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn day03_part1() { + let input = "\ +467..114.. +...*...... +..35..633. +......#... +617*...... +.....+.58. +..592..... +......755. +...$.*.... +.664.598.."; + let res = run_part1(&input); + assert_eq!(4361, res.unwrap()); + } + + #[test] + fn day03_part2() { + let input = ""; + let res = run_part2(&input); + assert_eq!(0, res.unwrap()); + } +} diff --git a/src/main.rs b/src/main.rs index 96d6d6e..2c9b7c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use std::error::Error; pub mod day00; pub mod day01; pub mod day02; +pub mod day03; fn main() { let args: Vec = env::args().collect(); @@ -25,6 +26,7 @@ fn run(day: &str, input_file: &str) -> Result<(), Box> { "day00" => day00::run(input_file)?, "day01" => day01::run(input_file)?, "day02" => day02::run(input_file)?, + "day03" => day03::run(input_file)?, _ => return Err(format!("unknown day \"{day}\"").into()), } Ok(()) -- 2.39.5