--- /dev/null
+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<u32, Box<dyn Error>> {
+ 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<u32, Box<dyn Error>> {
+ println!("Running {} - part 2", get_day());
+
+ Ok(0)
+}
+
+pub fn run(input: &str) -> Result<(), Box<dyn Error>> {
+ 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());
+ }
+}