bendn 2024-12-13
parent 57eb7ec · commit b7e7541
-rw-r--r--src/lib.rs180
1 files changed, 108 insertions, 72 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 6848c20..787be2b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -29,86 +29,122 @@
hint_assert_unchecked
)]
mod util;
-pub mod day11 {
+pub mod day12 {
use super::util::prelude::*;
- pub fn part1(i: &str) -> impl Display {
- const LUT: [u32; 10000000] = unsafe {
- std::mem::transmute::<[u8; 10000000 * 4], _>(*include_bytes!("../beeg2-larger-basic"))
- };
- p8(i)
- .map(|stone| C! { LUT[stone as usize] })
- .into_iter()
- .sum::<u32>()
- }
+ const SIZE: usize = 140;
+ #[no_mangle]
+ pub fn part2(i: &str) -> impl Display {
+ 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);
- fn nat<const N: usize>(x: [&u8; N]) -> u32 {
- x.into_iter().fold(0, |acc, x| acc * 10 + (x - b'0') as u32)
- }
+ 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);
- pub fn part2(i: &str) -> impl Display {
- static mut lut: [u64; 10000000] = unsafe {
- std::mem::transmute::<[u8; 10000000 * 8], _>(*include_bytes!("../beeg-basic"))
+ *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);
+ }
+ }
+
+ 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])
};
- p8(i)
- .map(|stone| C! { lut[stone as usize] })
- .into_iter()
- .sum::<u64>()
+ (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 p8(i: &str) -> [u32; 8] {
- let mut i = &i.as_bytes()[..i.len() - 1];
- use std::mem::MaybeUninit as MU;
- let mut arr = [const { MU::<u32>::uninit() }; 8];
- for j in 0..7 {
- arr[j].write(match i {
- [一, b' ', rest @ ..] => {
- i = rest;
- nat([一])
- }
- [一, 二, b' ', rest @ ..] => {
- i = rest;
- nat([一, 二])
- }
- [一, 二, 三, b' ', rest @ ..] => {
- i = rest;
- nat([一, 二, 三])
- }
- [一, 二, 三, 四, b' ', rest @ ..] => {
- i = rest;
- nat([一, 二, 三, 四])
- }
- [一, 二, 三, 四, 五, b' ', rest @ ..] => {
- i = rest;
- nat([一, 二, 三, 四, 五])
- }
- [一, 二, 三, 四, 五, 六, b' ', rest @ ..] => {
- i = rest;
- nat([一, 二, 三, 四, 五, 六])
- }
- [一, 二, 三, 四, 五, 六, 七, b' ', rest @ ..] => {
- i = rest;
- nat([一, 二, 三, 四, 五, 六, 七])
- }
- [一, 二, 三, 四, 五, 六, 七, 八, b' ', rest @ ..] => {
- i = rest;
- nat([一, 二, 三, 四, 五, 六, 七, 八])
+ #[no_mangle]
+ pub fn part1(i: &str) -> impl Display {
+ 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 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
}
- _ => shucks!(),
- });
+ *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);
+ }
}
- arr[7].write(match i {
- [一] => nat([一]),
- [一, 二] => nat([一, 二]),
- [一, 二, 三] => nat([一, 二, 三]),
- [一, 二, 三, 四] => nat([一, 二, 三, 四]),
- [一, 二, 三, 四, 五] => nat([一, 二, 三, 四, 五]),
- [一, 二, 三, 四, 五, 六] => nat([一, 二, 三, 四, 五, 六]),
- [一, 二, 三, 四, 五, 六, 七] => nat([一, 二, 三, 四, 五, 六, 七]),
- [一, 二, 三, 四, 五, 六, 七, 八] => nat([一, 二, 三, 四, 五, 六, 七, 八]),
- _ => shucks!(),
- });
- unsafe { MU::array_assume_init(arr) }
+
+ 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>()
}
}