From 95122bb4ca130a68dbd1c6692a38717b763dcceb Mon Sep 17 00:00:00 2001 From: YK Date: Mon, 25 Nov 2024 15:23:15 +0300 Subject: [PATCH] solution: day 13 (dfs) --- src/days.rs | 2 +- src/days/d13.rs | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/days/d13.rs diff --git a/src/days.rs b/src/days.rs index bae5f25..855a7cb 100644 --- a/src/days.rs +++ b/src/days.rs @@ -10,7 +10,7 @@ pub mod d9; pub mod d10; pub mod d11; pub mod d12; -// pub mod d13; +pub mod d13; // pub mod d14; // pub mod d15; // pub mod d16; diff --git a/src/days/d13.rs b/src/days/d13.rs new file mode 100644 index 0000000..b45b0c3 --- /dev/null +++ b/src/days/d13.rs @@ -0,0 +1,74 @@ +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +use crate::prelude::*; + +pub type O = usize; + +const INPUT: usize = 1358; + + +fn is_wall (y: usize, x: usize) -> bool { + ((x*x + 3*x + 2*x*y + y + y*y) + INPUT).count_ones() % 2 != 0 +} + +fn next ((y, x, len): (usize, usize, usize)) -> Vec<(usize, usize, usize)> { + const cand: [(isize, isize); 4] = [(0, -1), (0, 1), (-1, 0), (1, 0)]; + + cand.into_iter().filter_map(|(dy, dx)| { + let ny = y.checked_add_signed(dy); + let nx = x.checked_add_signed(dx); + + match (ny, nx) { + (Some(y), Some(x)) => if is_wall(y, x) { None } else { Some((y, x, len + 1)) }, + _ => None + } + }).collect() +} + +fn solve (visited: &mut M<(usize, usize), usize>) { + let mut stack = vec![(1, 1, 0)]; + while !stack.is_empty() { + let c @ (y, x, len) = stack.pop().unwrap(); + + *visited.entry((y, x)).or_default() = len; + for n @ (ny, nx, nl) in next(c) { + if !visited.contains_key(&(ny, nx)) || visited.get(&(ny, nx)).is_some_and(|&old| old > nl) { + stack.push(n); + } + } + } +} + +fn _silver () -> O { + let mut visited = M::new(); + solve(&mut visited); + *visited.get(&(39, 31)).unwrap() +} + +fn _gold () -> O { + let mut visited = M::new(); + solve(&mut visited); + visited.values().filter(|&&e| e <= 50).count() +} + + + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn silver () { + let ans = _silver(); + + assert_eq!(ans, 96) + } + + #[test] + fn gold () { + let ans = _gold(); + + assert_eq!(ans, 141) + } +}