heh
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 81 |
1 files changed, 59 insertions, 22 deletions
diff --git a/src/main.rs b/src/main.rs index 44991c7..3095717 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,29 +33,67 @@ )] extern crate test; pub mod util; -use std::sync::OnceLock; - pub use util::prelude::*; +const SIZE: usize = 140; -#[no_mangle] -pub unsafe fn p1(i: &str) -> impl Display { - let i = i.as_bytes().trim_ascii_end(); - let mut o = [0u32; 8]; - const LUT: [u32; 10000000] = unsafe { - std::mem::transmute::<[u8; 10000000 * 4], _>(*include_bytes!("../beeg2-larger-basic")) - }; - reading::κ(i, &mut o); - o.into_iter().map(|stone| C!{ LUT[stone as usize] }).sum::<u32>() +fn explore( + (x, y): (usize, usize), + handled: &mut [[bool; 140]; 140], + char: u8, + get: &mut impl FnMut(usize, usize) -> Option<u8>, + tot: &mut u32, + count: &mut u32, +) { + if get(x, y) == Some(char) && handled[y][x] == false { + handled[y][x] = true; + // αbβ + // a.c + // γdδ + let α = get(x.wrapping_sub(1), y.wrapping_sub(1)) != Some(char); + let β = get(x.wrapping_add(1), y.wrapping_sub(1)) != Some(char); + let γ = get(x.wrapping_sub(1), y.wrapping_add(1)) != Some(char); + let δ = get(x.wrapping_add(1), y.wrapping_add(1)) != Some(char); + + let a = get(x.wrapping_sub(1), y) != Some(char); + let b = get(x, y.wrapping_sub(1)) != Some(char); + let c = get(x.wrapping_add(1), y) != Some(char); + let d = get(x, y.wrapping_add(1)) != Some(char); + fn u(a: bool) -> u32 { + a as u32 + } + // *tot += u(a) + u(b) + u(c) + u(d); + + *tot += u(a & b) + u(b & c) + u(c & d) + u(a & d); + *tot += u(!a & !b & α) + u(!b & !c & β) + u(!c & !d & δ) + u(!a & !d & γ); + *count += 1; + + explore((x.wrapping_sub(1), y), handled, char, get, tot, count); + explore((x + 1, y), handled, char, get, tot, count); + explore((x, y + 1), handled, char, get, tot, count); + explore((x, y.wrapping_sub(1)), handled, char, get, tot, count); + } } #[no_mangle] -pub unsafe fn p2(i: &str) -> impl Display { - let i = i.as_bytes().trim_ascii_end(); - let mut o = [0u64; 8]; - const LUT: [u64; 10000000] = - unsafe { std::mem::transmute::<[u8; 10000000 * 8], _>(*include_bytes!("../beeg-basic")) }; - reading::κ(i, &mut o); - o.into_iter().map(|stone| C! { LUT[stone as usize] }).sum::<u64>() +pub fn run(i: &str) -> impl Display { + let grid = unsafe { i.as_bytes().as_chunks_unchecked::<{ SIZE + 1 }>() }; + let handled = &mut [[false; SIZE]; SIZE]; + let mut get = |x: usize, y: usize| { + unsafe { core::hint::assert_unchecked(grid.len() == SIZE) }; + (x < SIZE && y < SIZE).then(|| grid[y][x]) + }; + (0..SIZE) + .flat_map(move |y| (0..SIZE).map(move |x| (x, y))) + .filter_map(|(x, y)| { + let mut sides = 0; + let mut area = 0; + (!handled[y][x]).then(|| { + let char = C! { grid[y][x]}; + explore((x, y), handled, char, &mut get, &mut sides, &mut area); + area * sides + }) + }) + .sum::<u32>() } fn main() { @@ -66,13 +104,12 @@ fn main() { // s.push_str(i);i // } // std::fs::write("src/inp.txt", s); - println!("{}", unsafe { p1(i) }); - println!("{}", unsafe { p2(i) }); - // println!("{}", p1(i)); + #[allow(unused_unsafe)] + println!("{}", unsafe { run(i) }); } #[bench] fn bench(b: &mut test::Bencher) { let i = boxd(include_str!("inp.txt")); - b.iter(|| unsafe { p1(i) }); + b.iter(|| unsafe { run(i) }); } |