heh
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs151
1 files changed, 20 insertions, 131 deletions
diff --git a/src/main.rs b/src/main.rs
index ee8aab6..6c4c765 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -70,146 +70,35 @@ use std::{
use swizzle::array;
pub use util::prelude::*;
#[unsafe(no_mangle)]
-pub unsafe fn max(data: &[u8; 99]) -> u8 {
- let v0 = u8x64::from_slice(&data[0..64]);
- let v1 = u8x32::from_slice(&data[64..96]).resize::<64>(0);
- let mut mx = v0.simd_max(v1).reduce_max();
- for &b in &data[96..] {
- if b > mx {
- mx = b;
- }
- }
- mx
-}
-
-#[unsafe(no_mangle)]
-pub unsafe fn max89(data: &[u8; 89]) -> u8 {
- let v0 = u8x64::from_slice(&data[0..64]);
- let v1 = u8x32::load_or_default(&data[64..]).resize::<64>(0);
- v0.simd_max(v1).reduce_max()
-}
-
-pub unsafe fn max2(data: &[u8]) -> u8 {
- if data.len() == 1 {
- return data[0];
- }
- let start = u8x64::load_or_default(data);
- if data.len() > 64 {
- let extra = u8x64::load_or_default(&data[64..]);
- start.simd_max(extra).reduce_max()
- } else {
- start.reduce_max()
- }
-}
-#[unsafe(no_mangle)]
-#[inline(always)]
-// https://stackoverflow.com/a/77709227
-unsafe fn maxi32(v: u8x32) -> u8 {
- let v: u16x16 = transmute(v);
- //indexes
- const even: u16x16 = u16x16::from_array([
- 0xff00, 0xff02, 0xff04, 0xff06, 0xff08, 0xff0a, 0xff0c, 0xff0e, 0xff10, 0xff12, 0xff14,
- 0xff16, 0xff18, 0xff1a, 0xff1c, 0xff1e,
- ]);
- let odd = even + u16x16::splat(1);
- let vu16 = (v & u16x16::splat(0xff00u16) ^ odd).simd_min(v << 8 ^ even);
- _mm_cvtsi128_si32(_mm_minpos_epu16(transmute(
- vu16.extract::<0, 8>().simd_min(vu16.extract::<8, 8>()),
- ))) as u8
-}
-#[unsafe(no_mangle)]
-unsafe fn maxi(data: &[u8]) -> (u8, u8) {
- if data.len() > 96 {
- let f1 = maxi32(u8x32::from_slice(&data[..32]));
- let f2 = 32 + maxi32(u8x32::from_slice(&data[32..64]));
- let f3 = 64 + maxi32(u8x32::from_slice(&data[64..96]));
-
- let Left(a, b) = Left(data.get(98).copied().unwrap_or(0), 98)
- .max(Left(data.get(97).copied().unwrap_or(0), 97))
- .max(Left(data.get(96).copied().unwrap_or(0), 96))
- .max(Left(*data.get_unchecked(f3 as usize), f3))
- .max(Left(*data.get_unchecked(f2 as usize), f2))
- .max(Left(*data.get_unchecked(f1 as usize), f1));
- (a, b)
- } else if data.len() > 64 {
- let start = u8x32::from_slice(&data[..32]);
- let extra = u8x32::from_slice(&data[32..64]);
- let f1 = maxi32(start);
- let f2 = 32 + maxi32(extra);
- let f3 = 64 + maxi32(u8x32::load_or_default(&data[64..]));
- let Left(a, b) = Left(*data.get_unchecked(f3 as usize), f3)
- .max(Left(*data.get_unchecked(f2 as usize), f2))
- .max(Left(*data.get_unchecked(f1 as usize), f1));
- (a, b)
- } else if data.len() > 32 {
- let start = u8x32::from_slice(&data[..32]);
- let extra = u8x32::load_or_default(&data[32..]);
- let f1 = maxi32(start);
- let f2 = 32 + maxi32(extra);
- let Left(a, b) = std::cmp::max(
- Left(*data.get_unchecked(f2 as usize), f2),
- Left(*data.get_unchecked(f1 as usize), f1),
- );
- (a, b)
- } else {
- let start = u8x32::load_or_default(&data);
- let x = maxi32(start);
- (*data.get_unchecked(x as usize), x)
- }
-}
-#[unsafe(no_mangle)]
#[implicit_fn::implicit_fn]
pub unsafe fn p1(x: &'static [u8; ISIZE]) -> impl Debug {
- core::hint::assert_unchecked(x.len() == 200 * 101);
- x.as_chunks_unchecked::<101>()
- .into_iter()
- .map(|l| {
- let l = l.get_unchecked(..100);
- let l_ = l.get_unchecked(..l.len() - 1);
- let el = max(unsafe { &*(l_.as_ptr() as *const [u8; 99]) });
- let i = memchr::memchr(el, l_).unwrap_unchecked();
-
- let n = (el - b'0') as u64;
- let l_ = l.get_unchecked(i as usize + 1..);
- let el = max2(l_);
- (n * 10) + (el - b'0') as u64
- })
- .sum::<u64>()
-}
-
-#[unsafe(no_mangle)]
-pub unsafe fn p2(x: &'static [u8; ISIZE]) -> impl Debug {
- core::hint::assert_unchecked(x.len() == 200 * 101);
- x.as_chunks_unchecked::<101>()
- .into_iter()
- .map(|l| {
- let mut l = l.get_unchecked(..100);
-
- let l_ = l.get_unchecked(..l.len() - 11);
- let (el, i) = maxi(l_);
- let mut n = (el - b'0') as u64;
- l = l.get_unchecked(i as usize + 1..);
-
- for i in 1..11 {
- let l_ = l.get_unchecked(..l.len() + i - 11);
- let (el, i) = maxi(l_);
- n *= 10;
- n += (el - b'0') as u64;
- l = l.get_unchecked(i as usize + 1..);
+ let mut grid = x.chunked::<{ 136 + 1 }>();
+ let mut tot = 0;
+ loop {
+ let mut removed = 0;
+ for roll in grid.clone().find_iter(b'@') {
+ let nb = util::nb(roll)
+ .map(|(x, y)| grid.get(y).and_then(_.get(x)).is_some_and(*_ == b'@') as u8)
+ .sum();
+ if nb < 4 {
+ grid[roll.1][roll.0] = b'.';
+ removed += 1;
}
-
- let el = max2(l);
- n * 10 + (el - b'0') as u64
- })
- .sum::<u64>()
+ }
+ tot += removed;
+ if removed == 0 {
+ return tot;
+ }
+ }
}
+
const ISIZE: usize = include_bytes!("inp.txt").len();
fn main() {
- unsafe { println!("{:?}", p2(include_bytes!("inp.txt"))) };
+ unsafe { println!("{:?}", p1(include_bytes!("inp.txt"))) };
}
#[bench]
fn benc(b: &mut test::Bencher) {
let i = boxd(include_bytes!("inp.txt"));
- b.iter(|| unsafe { p2(i) });
+ b.iter(|| unsafe { p1(i) });
}