heh
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 485 |
1 files changed, 431 insertions, 54 deletions
diff --git a/src/main.rs b/src/main.rs index 3153a83..fdacfbc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,63 +36,440 @@ pub mod util; use atools::CollectArray; pub use util::prelude::*; -const W: i32 = 101; -const H: i32 = 103; -#[no_mangle] -pub fn run(i: &str) -> impl Display { - let mut grids = [0; 4]; - i.行() - .map(|x| { - let ((px, py), (vx, vy)) = x.μ(' ').mb(|x| x.μ1('=').μκ::<i32>(',').Δ()); - let x = (px + vx * 100).rem_euclid(W); - let y = (py + vy * 100).rem_euclid(H); - let w = W / 2; - let h = H / 2; - if x < w && y < h { - grids[0] += 1; - } else if x < w && y > h { - grids[1] += 1; - } else if x > w && y < h { - grids[2] += 1; - } else if x > w && y > h { - grids[3] += 1; - } +const SIZE: usize = 50; +// enum Bloc { +// Wall, +// Block, +// Space, +// } + +// impl Bloc { +// fn push((x, y): (usize, usize), dir: Dir, grid: &mut [[Bloc; SIZE]], commit: bool) -> bool { +// match dir { +// Dir::N => match grid[y - 1][x] {}, +// Dir::E => todo!(), +// Dir::S => todo!(), +// Dir::W => todo!(), +// } +// } +// } +// impl std::fmt::Debug for Bloc { +// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +// match self { +// Wall => write!(f, "##"), +// Block => write!(f, "[]"), +// Space => write!(f, ".."), +// } +// } +// } +// use Bloc::*; +pub unsafe fn p2(i: &str) -> impl Display { + let i = i.as_bytes(); + let bot = memchr::memchr(b'@', i).ψ(); + let (mut x, mut y) = ((bot % (SIZE + 1)) * 2, bot / (SIZE + 1)); + let grid = i[..(SIZE + 1) * SIZE] + .array_chunks::<{ SIZE + 1 }>() + .flat_map(|x| { + x.iter().take(SIZE).copied().flat_map(|x| match x { + b'#' => [x; 2], + b'O' => *b"[]", + b'@' | b'.' => *b"..", + _ => unreachable!(), + }) }) - .Θ(); - grids.iter().product::<u32>() + .collect::<Vec<_>>() + .leak() + .as_chunks_unchecked_mut::<{ SIZE * 2 }>(); + // for y in 0..SIZE { + // for x in 0..SIZE * 2 { + // if (px, py) == (x, y) { + // print!("@"); + // } else { + // print!("{}", grid[y][x] as char); + // } + // } + // println!(); + // } + // println!("{grid/:?}"); + // let grid = i[..(SIZE + 1) * SIZE] + // .to_vec() + // .leak() + // .as_chunks_unchecked_mut::<{ SIZE + 1 }>(); + // grid[y][x * 2] = b'.'; + let i = &i[((SIZE + 1) * SIZE) + 1..]; + fn push((x, y): (usize, usize), dir: Dir, grid: &mut [[u8; SIZE * 2]], commit: bool) -> bool { + match dir { + Dir::N => match [grid[y - 1][x], grid[y - 1][x + 1]] { + [_, b'#'] | [b'#', _] => {} + [b'.', b'.'] => { + if commit { + grid[y - 1][x] = b'['; + grid[y - 1][x + 1] = b']'; + grid[y][x] = b'.'; + grid[y][x + 1] = b'.'; + } + return true; + // swap(&mut grid[y - 1][x], &mut grid[y][x]), + } + [b']', b'['] => { + let val = push((x - 1, y - 1), dir, grid, false) + && push((x + 1, y - 1), dir, grid, false); + if commit && val { + push((x - 1, y - 1), dir, grid, commit); + push((x + 1, y - 1), dir, grid, commit); + grid[y - 1][x] = b'['; + grid[y - 1][x + 1] = b']'; + grid[y][x] = b'.'; + grid[y][x + 1] = b'.'; + } + return val; + } + [b']', b'.'] => { + let val = push((x - 1, y - 1), dir, grid, commit); + if commit && val { + grid[y - 1][x] = b'['; + grid[y - 1][x + 1] = b']'; + grid[y][x] = b'.'; + grid[y][x + 1] = b'.'; + } + return val; + } + [b'.', b'['] => { + let val = push((x + 1, y - 1), dir, grid, commit); + if commit && val { + grid[y - 1][x] = b'['; + grid[y - 1][x + 1] = b']'; + grid[y][x] = b'.'; + grid[y][x + 1] = b'.'; + } + return val; + } + // "simple" case + [b'[', b']'] => { + let val = push((x, y - 1), dir, grid, commit); + if val && commit { + grid[y - 1][x] = b'['; + grid[y - 1][x + 1] = b']'; + grid[y][x] = b'.'; + grid[y][x + 1] = b'.'; + } + return val; + } + x => unreachable!("{x:?}"), + }, + Dir::S => match [grid[y + 1][x], grid[y + 1][x + 1]] { + [_, b'#'] | [b'#', _] => {} + [b'.', b'.'] => { + if commit { + grid[y + 1][x] = b'['; + grid[y + 1][x + 1] = b']'; + grid[y][x] = b'.'; + grid[y][x + 1] = b'.'; + } + return true; + // swap(&mut grid[y - 1][x], &mut grid[y][x]), + } + [b']', b'['] => { + let val = push((x - 1, y + 1), dir, grid, false) + && push((x + 1, y + 1), dir, grid, false); + if commit && val { + push((x - 1, y + 1), dir, grid, commit); + push((x + 1, y + 1), dir, grid, commit); + grid[y + 1][x] = b'['; + grid[y + 1][x + 1] = b']'; + grid[y][x] = b'.'; + grid[y][x + 1] = b'.'; + } + return val; + } + [b']', b'.'] => { + let val = push((x - 1, y + 1), dir, grid, commit); + if commit && val { + grid[y + 1][x] = b'['; + grid[y + 1][x + 1] = b']'; + grid[y][x] = b'.'; + grid[y][x + 1] = b'.'; + } + return val; + } + [b'.', b'['] => { + let val = push((x + 1, y + 1), dir, grid, commit); + if commit && val { + grid[y + 1][x] = b'['; + grid[y + 1][x + 1] = b']'; + grid[y][x] = b'.'; + grid[y][x + 1] = b'.'; + } + return val; + } + [b'[', b']'] => { + let val = push((x, y + 1), dir, grid, commit); + if val && commit { + grid[y + 1][x] = b'['; + grid[y + 1][x + 1] = b']'; + grid[y][x] = b'.'; + grid[y][x + 1] = b'.'; + } + return val; + } + x => unreachable!("{x:?}"), + }, + Dir::E => match grid[y][x + 2] { + b'.' => { + grid[y][x + 2] = b']'; + grid[y][x + 1] = b'['; + grid[y][x] = b'.'; + return true; + // swap(&mut grid[y - 1][x], &mut grid[y][x]), + } + b'[' => { + if push((x + 2, y), dir, grid, commit) { + grid[y][x + 2] = b']'; + grid[y][x + 1] = b'['; + grid[y][x] = b'.'; + return true; + } + } + b'#' => {} + x => unreachable!("{}", x as char), + }, + + Dir::W => match grid[y][x - 1] { + b'.' => { + grid[y][x - 1] = b'['; + grid[y][x] = b']'; + grid[y][x + 1] = b'.'; + return true; + // swap(&mut grid[y - 1][x], &mut grid[y][x]), + } + b']' => { + if push((x - 2, y), dir, grid, commit) { + grid[y][x - 1] = b'['; + grid[y][x] = b']'; + grid[y][x + 1] = b'.'; + return true; + } + } + b'#' => {} + x => unreachable!("{}", x as char), + }, + } + false + } + for input in i { + // println!("{}", *input as char); + match input { + b'<' => match grid[y][x - 1] { + b'.' => x = x - 1, + b'#' => (), + b']' => { + if push((x - 2, y), Dir::W, grid, true) { + x = x - 1; + } + } + x => unreachable!("{}", x as char), + }, + b'>' => match grid[y][x + 1] { + b'.' => x = x + 1, + b'#' => (), + b'[' => { + if push((x + 1, y), Dir::E, grid, true) { + x = x + 1; + } + } + x => unreachable!("{}", x as char), + }, + + b'^' => match grid[y - 1][x] { + b'.' => y = y - 1, + b'#' => (), + b']' => { + if push((x - 1, y - 1), Dir::N, grid, true) { + y = y - 1; + } + } + b'[' => { + if push((x, y - 1), Dir::N, grid, true) { + y = y - 1; + } + } + x => unreachable!("{}", x as char), + }, + b'v' => match grid[y + 1][x] { + b'.' => y = y + 1, + b'#' => (), + b'[' => { + if push((x, y + 1), Dir::S, grid, true) { + y = y + 1; + } + } + b']' => { + if push((x - 1, y + 1), Dir::S, grid, true) { + y = y + 1; + } + } + x => unreachable!("{}", x as char), + }, + _ => {} + } + // grid[y][x] = b'@'; + // for row in &*grid { + // println!("{}", row.p()); + // } + // grid[y][x] = b'.'; + } + let mut sum = 0; + for (row, y) in grid.into_iter().ι::<u32>() { + for (col, x) in row.into_iter().ι::<u32>() { + if *col == b'[' { + sum += 100 * y + x + } + } + } + + sum } #[no_mangle] -pub fn p2(i: &str) -> impl Display { - let mut positions = Vec::<((i32, i32), (i32, i32))>::with_capacity(500); - const W: i32 = 101; - const H: i32 = 103; - i.行().for_each(|x| { - positions.push(x.μ(' ').mb(|x| x.μ1('=').μκ::<i32>(',').Δ())); - }); - let bx = (0..W) - .map(|seconds| { - positions - .iter() - .map(move |&((x, _), (vx, _))| (x + vx * seconds).rem_euclid(W).abs_diff(W / 2)) - .sum::<u32>() - }) - .enumerate() - .min_by_key(|&(_, x)| x) - .unwrap() - .0 as i32; - let by = (0..H) - .map(|seconds| { - positions - .iter() - .map(move |&((_, x), (_, vx))| (x + vx * seconds).rem_euclid(H).abs_diff(H / 2)) - .sum::<u32>() - }) - .enumerate() - .min_by_key(|&(_, x)| x) - .unwrap() - .0 as i32; - bx + ((51 * (by - bx)) % H) * W +pub unsafe fn run(i: &str) -> impl Display { + let i = i.as_bytes(); + let bot = memchr::memchr(b'@', i).ψ(); + let (mut x, mut y) = (bot % (SIZE + 1), bot / (SIZE + 1)); + let grid = i[..(SIZE + 1) * SIZE] + .to_vec() + .leak() + .as_chunks_unchecked_mut::<{ SIZE + 1 }>(); + grid[y][x] = b'.'; + let i = &i[((SIZE + 1) * SIZE) + 1..]; + fn push((x, y): (usize, usize), dir: Dir, grid: &mut [[u8; SIZE + 1]]) -> bool { + match dir { + Dir::N => match grid[y - 1][x] { + b'.' => { + grid[y - 1][x] = b'O'; + grid[y][x] = b'.'; + return true; + // swap(&mut grid[y - 1][x], &mut grid[y][x]), + } + b'O' => { + if push((x, y - 1), dir, grid) { + grid[y - 1][x] = b'O'; + grid[y][x] = b'.'; + return true; + } + } + b'#' => {} + x => unreachable!("{}", x as char), + }, + Dir::E => match grid[y][x + 1] { + b'.' => { + grid[y][x + 1] = b'O'; + grid[y][x] = b'.'; + return true; + // swap(&mut grid[y - 1][x], &mut grid[y][x]), + } + b'O' => { + if push((x + 1, y), dir, grid) { + grid[y][x + 1] = b'O'; + grid[y][x] = b'.'; + return true; + } + } + b'#' => {} + x => unreachable!("{}", x as char), + }, + Dir::S => match grid[y + 1][x] { + b'.' => { + grid[y + 1][x] = b'O'; + grid[y][x] = b'.'; + return true; + // swap(&mut grid[y - 1][x], &mut grid[y][x]), + } + b'O' => { + if push((x, y + 1), dir, grid) { + grid[y + 1][x] = b'O'; + grid[y][x] = b'.'; + return true; + } + } + b'#' => {} + x => unreachable!("{}", x as char), + }, + Dir::W => match grid[y][x - 1] { + b'.' => { + grid[y][x - 1] = b'O'; + grid[y][x] = b'.'; + return true; + // swap(&mut grid[y - 1][x], &mut grid[y][x]), + } + b'O' => { + if push((x - 1, y), dir, grid) { + grid[y][x - 1] = b'O'; + grid[y][x] = b'.'; + return true; + } + } + b'#' => {} + x => unreachable!("{}", x as char), + }, + } + false + } + for input in i { + match input { + b'<' => match grid[y][x - 1] { + b'.' => x = x - 1, + b'#' => (), + b'O' => { + if push((x - 1, y), Dir::W, grid) { + x = x - 1; + } + } + x => unreachable!("{}", x as char), + }, + b'>' => match grid[y][x + 1] { + b'.' => x = x + 1, + b'#' => (), + b'O' => { + if push((x + 1, y), Dir::E, grid) { + x = x + 1; + } + } + x => unreachable!("{}", x as char), + }, + + b'^' => match grid[y - 1][x] { + b'.' => y = y - 1, + b'#' => (), + b'O' => { + if push((x, y - 1), Dir::N, grid) { + y = y - 1; + } + } + x => unreachable!("{}", x as char), + }, + b'v' => match grid[y + 1][x] { + b'.' => y = y + 1, + b'#' => (), + b'O' => { + if push((x, y + 1), Dir::S, grid) { + y = y + 1; + } + } + x => unreachable!("{}", x as char), + }, + _ => {} + } + } + let mut sum = 0; + for (row, y) in grid.into_iter().ι::<u32>() { + for (col, x) in row.into_iter().ι::<u32>() { + if *col == b'O' { + sum += 100 * y + x + } + } + } + + sum } fn main() { @@ -101,7 +478,7 @@ fn main() { // for i in 0..1280 { let i = include_str!("inp.txt"); // s.push_str(i);i - // } + // }w // std::fs::write("src/inp.txt", s); #[allow(unused_unsafe)] println!("{}", unsafe { p2(i) }); |