From: alex <> Date: Tue, 10 Dec 2024 08:41:00 +0000 (+0100) Subject: Day10 - part 1 X-Git-Url: https://aoc.elinar.fr/?a=commitdiff_plain;h=440825b613ee1c96ec3d2e11eeee5f019dd31e10;p=aoc_2024 Day10 - part 1 --- diff --git a/src/day10.rs b/src/day10.rs new file mode 100644 index 0000000..57b56a8 --- /dev/null +++ b/src/day10.rs @@ -0,0 +1,146 @@ +use std::error::Error; +use std::path::Path; +use std::collections::{HashMap, HashSet}; + +struct Puzzle { + map: HashMap<(isize, isize), u8>, + start_pos: Vec<(isize, isize)>, +} + +impl Puzzle { + pub fn new(input: &str) -> Self { + let mut map = HashMap::new(); + let mut start_pos = Vec::new(); + input.lines().enumerate() + .for_each(|(r, l)| { + l.as_bytes().into_iter().enumerate() + .for_each(|(c, b)| { + if *b != b'.' { + map.insert((r as isize, c as isize), *b); + if *b == b'0' { + start_pos.push((r as isize, c as isize)); + } + } + }); + }); + Self { map, start_pos } + } + + fn score(self: &Self, pos: (isize, isize), value: u8, visited: &mut HashSet<(isize, isize)>) -> u32 { + [(-1,0), (0,1), (1,0), (0,-1)].iter() + .map(|dij| (pos.0 + dij.0 as isize, pos.1 + dij.1 as isize)) + .map(|new_pos| { + match self.map.get(&new_pos) { + Some(&value_next) => { + if value_next == value + 1 { + if value_next == b'9' && !visited.contains(&new_pos) { + visited.insert(new_pos); + 1 + } + else { + self.score(new_pos, value_next, visited) + } + } + else { + 0 + } + }, + _ => { 0 } + } + }) + .sum() + } +} + +fn run_part1(input: &str) -> Result> { + println!("Running {} - part 1", get_day()); + + let puzzle = Puzzle::new(input); + let res = puzzle.start_pos.iter() + .map(|pos| { + let mut visited = HashSet::new(); + puzzle.score(*pos, b'0', &mut visited) + }) + .sum(); + + Ok(res) +} + +fn run_part2(input: &str) -> Result> { + println!("Running {} - part 2", get_day()); + + Ok(0) +} + +pub fn run(input: &str) -> Result<(), Box> { + let res = run_part1(&input)?; + println!("{res}"); + + let res = run_part2(&input)?; + println!("{res}"); + + Ok(()) +} + +fn get_day() -> String { + let filename = file!(); + Path::new(filename).file_stem().unwrap().to_str().unwrap().to_string() +} + +#[cfg(test)] +mod tests { + use super::*; + + static TEXT_INPUT_0: &str = "\ +0123 +1234 +8765 +9876"; + static TEXT_INPUT_1: &str = "\ +...0... +...1... +...2... +6543456 +7.....7 +8.....8 +9.....9"; + static TEXT_INPUT_2: &str = "\ +..90..9 +...1.98 +...2..7 +6543456 +765.987 +876.... +987...."; + static TEXT_INPUT_3: &str = "\ +10..9.. +2...8.. +3...7.. +4567654 +...8..3 +...9..2 +.....01"; + static TEXT_INPUT: &str = "\ +89010123 +78121874 +87430965 +96549874 +45678903 +32019012 +01329801 +10456732"; + + #[test] + fn test_part1() { + assert_eq!(1, run_part1(TEXT_INPUT_0).unwrap()); + assert_eq!(2, run_part1(TEXT_INPUT_1).unwrap()); + assert_eq!(4, run_part1(TEXT_INPUT_2).unwrap()); + assert_eq!(3, run_part1(TEXT_INPUT_3).unwrap()); + assert_eq!(36, run_part1(TEXT_INPUT).unwrap()); + } + + #[test] + fn test_part2() { + assert_eq!(0, run_part2(TEXT_INPUT).unwrap()); + } +} diff --git a/src/main.rs b/src/main.rs index a66cb4d..52ca4cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ pub mod day06; pub mod day07; pub mod day08; pub mod day09; +pub mod day10; fn main() { let args: Vec = env::args().collect(); @@ -44,6 +45,7 @@ fn run(day: &str, input_file: &str) -> Result<(), Box> { "day07" => day07::run(&input)?, "day08" => day08::run(&input)?, "day09" => day09::run(&input)?, + "day10" => day10::run(&input)?, _ => return Err(format!("unknown or unimplemented day \"{day}\"").into()), } Ok(())