heh
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 144 |
1 files changed, 37 insertions, 107 deletions
diff --git a/src/main.rs b/src/main.rs index 23f25a9..4da23d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,114 +18,44 @@ extern crate test; pub mod util; pub use util::prelude::*; -#[repr(u8)] -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] -enum D { - N, - E, - S, - W, -} - -macro_rules! csub { - ($a:ident -= $b:expr) => { - // faster than a overflowing sub :/ - $a = match $a.checked_sub($b) { - Some(x) => x, - None => break, - } - }; -} - -const SZ: u8 = 110; - -fn test(mat: &[[u8; SZ as usize + 1]; SZ as usize], p: (u8, u8), d: D) -> u16 { - use D::*; - let mut e = vec![0u128; SZ.nat()]; - // *three dimensions* omg - let mut been = vec![[0; 110]; 110]; - fn beam( - mat: &[[u8; SZ as usize + 1]; SZ as usize], - (mut x, mut y): (u8, u8), - mut d: D, - e: &mut [u128], - been: &mut [[u8; 110]], - ) { - loop { - if y >= SZ || x >= SZ { - break; - } - bits!(e[y.nat()] + x); - let w = (mat[y.nat()][x.nat()], d); - mat! { w { - (b'|', E | W) => { - if !bits!(been[x.nat()][y.nat()][d as u8]) { - bits!(been[x.nat()][y.nat()] + d as u8); - if let Some(v) = y.checked_sub(1) { - beam(mat, (x, v), N, e, been); - } - d = S; - y += 1; - } else { - return; - } - }, - (b'-', N | S) => { - if !bits!(been[x.nat()][y.nat()][d as u8]) { - bits!(been[x.nat()][y.nat()] + d as u8); - if let Some(v) = x.checked_sub(1) { - beam(mat, (v, y), W, e, been); - } - d = E; - x += 1; - } else { - return; - } - }, - (b'|' | b'.', N) => csub!(y -= 1), - (b'-' | b'.', E) => x += 1, - (b'|' | b'.', S) => y += 1, - (b'-' | b'.', W) => csub!(x -= 1), - (b'/', N) | (b'\\', S) => { - d = E; - x += 1; - }, - (b'/', E) | (b'\\', W) => { - d = N; - csub!(y -= 1); - }, - (b'/', S) | (b'\\', N) => { - d = W; - csub!(x -= 1); - }, - (b'/', W) | (b'\\', E) => { - d = S; - y += 1; - }, - }} - } - } - beam(mat, p, d, &mut e, &mut been); - e.iter().map(|x| x.count_ones() as u16).sum::<u16>() -} - -use rayon::prelude::*; -pub fn p2(mat: &[[u8; 111]; 110]) -> impl Display { - use D::*; - let a = (0..SZ).into_par_iter().map(|i| test(mat, (i, 0), S)).max(); - let b = (0..SZ).into_par_iter().map(|i| test(mat, (i, SZ), N)).max(); - let c = (0..SZ).into_par_iter().map(|i| test(mat, (0, i), E)).max(); - let d = (0..SZ).into_par_iter().map(|i| test(mat, (SZ, i), W)).max(); - a.α().max(b.α()).max(c.α()).max(d.α()) -} - -pub fn p1(mat: &[[u8; 111]; 110]) -> impl Display { - test(mat, (0, 0), D::E) -} - pub fn run(i: &str) -> impl Display { - let mat = unsafe { &*(i.as_bytes().as_ptr() as *const [[u8; 111]; 110]) }; - p1(mat) + let v = i.行().collect_vec(); + let g = util::LMap::new(|(x, y, δx, δy, gone): (i16, i16, i16, i16, i16)| { + Some( + [ + Dir::W + (x, y), + Dir::E + (x, y), + Dir::N + (x, y), + Dir::S + (x, y), + ] + .iter() + .filter_map(|&(nx, ny)| { + let ngon; + let nδx = nx - x; + let nδy = ny - y; + if nδx == δx && nδy == δy { + if gone == 3 { + return None; + } + ngon = gone + 1; + } else if (nδx == -δx && nδx != 0) || (nδy == -δy && nδy != 0) { + return None; + } else { + ngon = 1; + } + (nx >= 0 && nx < v[0].len() as i16 && ny >= 0 && ny < v.len() as i16).then(|| { + ( + (nx, ny, nδx, nδy, ngon), + (v[ny as usize][nx as usize] - b'0') as u32, + ) + }) + }) + .collect_vec(), + ) + }); + util::dijkstra(g, (0i16, 0i16, 0i16, 0i16, 0i16), |(x, y, _, _, _)| { + x == v[0].len() as i16 - 1 && y == v.len() as i16 - 1 + }) } fn main() { |