From 55688a124d845fed3f48f6325cceb6ba99673a39 Mon Sep 17 00:00:00 2001 From: YK Date: Fri, 6 Dec 2024 12:53:08 +0300 Subject: [PATCH] solution: day 6 --- src/days.rs | 2 +- src/days/d6.rs | 131 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 src/days/d6.rs diff --git a/src/days.rs b/src/days.rs index 4436c45..a44c1c7 100644 --- a/src/days.rs +++ b/src/days.rs @@ -3,7 +3,7 @@ pub mod d2; pub mod d3; pub mod d4; pub mod d5; -// pub mod d6; +pub mod d6; // pub mod d7; // pub mod d8; // pub mod d9; diff --git a/src/days/d6.rs b/src/days/d6.rs new file mode 100644 index 0000000..1acaf1a --- /dev/null +++ b/src/days/d6.rs @@ -0,0 +1,131 @@ +#![allow(non_upper_case_globals)] +use crate::prelude::*; + +pub type I = Vec>; +pub type O = usize; + +fn _parse (data: &str) -> I { + data.lines().map(|line| line.chars().collect()).collect() +} + +fn _traverse (data: &I) -> S<(usize, usize)> { + let (mut sy, mut sx) = data.iter().enumerate().find_map(|(y, row)| row.iter().position(|e| *e == '^').map(|x| (y, x))).unwrap(); + + let rows = data.len(); + let cols = data[0].len(); + + let mut s: S<(usize, usize)> = S::new(); + const dirs: [(isize, isize); 4] = [(-1, 0), (0, 1), (1, 0), (0, -1)]; + let mut dir = 0; + + loop { + + let (dy, dx) = dirs[dir]; + let ny = sy.checked_add_signed(dy); + let nx = sx.checked_add_signed(dx); + + match (ny, nx) { + (Some(ny), Some(nx)) if ny < rows && nx < cols => { + if data[ny][nx] == '#' { + dir = (dir + 1) % 4; + } else { + s.insert((ny, nx)); + sy = ny; + sx = nx; + } + }, + _ => break, + } + + } + + s +} + +fn _silver (data: I) -> O { + let ans = _traverse(&data); + ans.len() +} + +fn _gold (mut data: I) -> O { + let path = _traverse(&data); + let (sy, sx) = data.iter().enumerate().find_map(|(y, row)| row.iter().position(|e| *e == '^').map(|x| (y, x))).unwrap(); + data[sy][sx] = '.'; + + let rows = data.len(); + let cols = data[0].len(); + + const dirs: [(isize, isize); 4] = [(-1, 0), (0, 1), (1, 0), (0, -1)]; + + let mut loops = 0; + + 'outer : for (cy, cx) in path { + if cy == sy && cx == sx { continue; } + if data[cy][cx] == '.' { + data[cy][cx] = '#'; + + let mut y = sy; + let mut x = sx; + + let mut s: S<((usize, usize), usize)> = S::new(); + let mut dir = 0; + + 'inner : loop { + let (dy, dx) = dirs[dir]; + + if s.contains(&((y, x), dir)) { + loops += 1; + data[cy][cx] = '.'; + continue 'outer; + } + s.insert(((y, x), dir)); + + let ny = y.checked_add_signed(dy); + let nx = x.checked_add_signed(dx); + + match (ny, nx) { + (Some(ny), Some(nx)) if ny < rows && nx < cols => { + if data[ny][nx] == '#' { + dir = (dir + 1) % 4; + } else { + y = ny; + x = nx; + } + }, + _ => break 'inner, + } + + } + + data[cy][cx] = '.'; + } + } + + loops +} + +#[cfg(test)] +mod test { + use super::*; + + fn read () -> I { + let data = inc!(6); + _parse(data) + } + + #[test] + fn silver () { + let data = read(); + let ans = _silver(data); + + assert_eq!(ans, 4967) + } + + #[test] + fn gold () { + let data = read(); + let ans = _gold(data); + + assert_eq!(ans, 1789) + } +}