diff --git a/src/days.rs b/src/days.rs index 18c513c..7f0258a 100644 --- a/src/days.rs +++ b/src/days.rs @@ -7,7 +7,7 @@ pub mod d6; pub mod d7; pub mod d8; pub mod d9; -// pub mod d10; +pub mod d10; // pub mod d11; // pub mod d12; // pub mod d13; diff --git a/src/days/d10.rs b/src/days/d10.rs new file mode 100644 index 0000000..1d15952 --- /dev/null +++ b/src/days/d10.rs @@ -0,0 +1,103 @@ +use crate::prelude::*; + +pub type I1 = Vec>; +pub type I2 = Vec<(usize, usize)>; +pub type O = usize; + +fn _parse (data: &str) -> (I1, I2) { + data.trim().lines().enumerate().fold((vec![], vec![]), |(mut map, mut zeroes), (y, line)| { + let mut l = vec![]; + for (x, c) in line.trim().chars().enumerate() { + l.push(c); + if c == '0' { zeroes.push((y, x)); } + } + map.push(l); + (map, zeroes) + }) +} + +fn _dfs ( + pos @ (y, x): (usize, usize), + map: &[Vec], + visited: &mut S<(usize, usize)>, + silver: &mut S<(usize, usize)>, + gold: &mut O, +) { + visited.insert(pos); + + let current = map[y][x]; + if current == '9' { + silver.insert(pos); + *gold += 1; + return; + } + + let neighbors = [(-1, 0), (0, -1), (0, 1), (1, 0)].into_iter().filter_map(|(dy, dx)| match (y.checked_add_signed(dy), x.checked_add_signed(dx)) { + (Some(y), Some(x)) if y < map.len() && x < map[0].len() => Some((y, x)), + _ => None + }).filter(|&(y, x)| map[y][x] as u8 - current as u8 == 1); + + + let cloned = visited.clone(); + + for n in neighbors { + if !visited.contains(&n) { + _dfs(n, map, visited, silver, gold); + } + *visited = cloned.clone(); + } +} + +fn _solve ((map, zeroes): &(I1, I2)) -> (O, O) { + let (mut silver, mut gold) = (0, 0); + + for &z in zeroes { + let mut _sm = S::new(); + _dfs(z, &map, &mut S::new(), &mut _sm, &mut gold); + silver += _sm.len(); + } + (silver, gold) +} + +fn _silver (i: &(I1, I2)) -> O { + _solve(i).0 +} + +fn _gold (i: &(I1, I2)) -> O { + _solve(i).1 +} + +#[cfg(test)] +mod test { + use super::*; + + fn read () -> (I1, I2) { + let data = inc!(10); + _parse(data) + } + + #[test] + fn sample () { + let data = inc!("10_example"); + let data = _parse(data); + + assert_eq!(_silver(&data), 36); + assert_eq!(_gold(&data), 81); + } + + #[test] + fn silver () { + let data = read(); + let ans = _silver(&data); + + assert_eq!(ans, 694) + } + + #[test] + fn gold () { + let data = read(); + let ans = _gold(&data); + + assert_eq!(ans, 1497) + } +}