--- /dev/null
+use std::io::Read;
+use std::error::Error;
+use std::fs::File;
+
+use regex::Regex;
+
+pub fn run(input_file: &str) -> Result<(), Box<dyn Error>> {
+ 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<i32, Box<dyn Error>> {
+ 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<bool>> = Vec::new();
+ input.lines()
+ .for_each(|l| {
+ let mut symbol: Vec<bool> = 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<Vec<bool>>) -> 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::<i32>().unwrap();
+ }
+ })
+ });
+
+ Ok(res)
+}
+
+fn run_part2(input: &str) -> Result<i32, Box<dyn Error>> {
+ 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());
+ }
+}