heh
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 132 |
1 files changed, 32 insertions, 100 deletions
diff --git a/src/main.rs b/src/main.rs index f90282c..a4c1e1c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,116 +38,48 @@ pub use util::prelude::*; const WIDTH: usize = 71; pub unsafe fn run(x: &str) -> impl Display { - let mut grid = [[0; WIDTH + 1]; WIDTH + 1]; - let mut add = x.行().map(|x| x.μ(',').mb(|x| x.λ::<u8>())); - loop { - let x = add.next().unwrap(); - grid[x.1.nat()][x.0.nat()] = 1; - if util::dijkstra( - |x: (usize, usize)| { - [Dir::N + x, Dir::E + x, Dir::S + x, Dir::W + x] - .into_iter() - .filter(|&(x, y)| grid.get(y).and_then(|y| y.get(x)) == Some(&0)) - .map(|x| (x, 1)) - }, - (0, 0), - |x| x == (WIDTH, WIDTH), - ) - .is_none() - { - return format!("{x:?}"); - } - } + let mut i = x.as_bytes(); + let towels = i + .take_line() + .ψ() + .to_vec() + .leak() + .split(|x| *x == b',') + .map(|x| x.trim_ascii()) + .collect_vec() + .leak(); + i.take_line(); - // 0 -} - -pub struct UnionFind { - pub p: [u16; 5184], - pub s: [u16; 5184], -} - -impl UnionFind { - pub const fn new() -> Self { - Self { - s: [1; 5184], - p: car::map!(atools::range(), |x| x as u16), - } - } - - pub const fn find(&mut self, key: u16) -> u16 { - if unsafe { *self.p.as_ptr().add(key as usize) } == key { - return key; - } - let parent = self.find(unsafe { *self.p.as_ptr().add(key as usize) }); - unsafe { *self.p.as_mut_ptr().add(key as usize) = parent }; - parent - } - - pub const fn union(&mut self, a: u16, b: u16) -> bool { - let α = self.find(a); - let β = self.find(b); - if α == β { - return false; - } - let a = unsafe { *self.s.as_ptr().add(α as usize) }; - let b = unsafe { *self.s.as_ptr().add(β as usize) }; - if a >= b { - unsafe { *self.s.as_mut_ptr().add(α as usize) += b }; - unsafe { *self.p.as_mut_ptr().add(β as usize) = α }; - } else { - unsafe { *self.s.as_mut_ptr().add(β as usize) += a }; - unsafe { *self.p.as_mut_ptr().add(α as usize) = β }; - } - true - } -} - -pub fn part2(x: &str) -> impl Display { - let add = x.行().map(|x| x.μ(',').mb(|x| x.λ::<u8>())); - macro_rules! dex { - ($x:expr, $y:expr) => { - unsafe { - (($y as u16) - .unchecked_mul((WIDTH as u16 + 1)) - .unchecked_add($x as u16)) + i.行() + .map(|x| { + fn ck(x: &'static [u8], towels: &'static [&[u8]]) -> usize { + util::memoize! { + |(x, towels) in (&[u8], &[&[u8]])| -> usize { + if let [] = x { + return 1; + } + towels + .iter() + .filter(|&&y| x.starts_with(y)) + .map(|y| ck(&x[y.len()..], towels)) + .sum::<usize>() + }; + (x, towels) + } } - }; - } - const W: u8 = WIDTH as u8; - const UF: UnionFind = { - let mut f = UnionFind::new(); - let mut i = 0; - while i < W - 1 { - f.union(dex!(i + 1, 0), dex!(i + 2, 0)); - f.union(dex!(i, W), dex!(i + 1, W)); - f.union(dex!(0, i + 1), dex!(0, i + 2)); - f.union(dex!(W, i), dex!(W, i + 1)); - i += 1; - } - f - }; - let mut uf = UF; - for (x, y) in add { - let i = dex!(x, y); - uf.union(i, dex!(x + 1, y)); - uf.union(i, dex!(x, y + 1)); - uf.union(i, dex!(x + 1, y + 1)); - if uf.find(dex!(0, 1)) == uf.find(dex!(1, 0)) { - return format!("{},{}", x, y); - } - } - dang!(); + ck(x.to_vec().leak(), towels) + }) + .sum::<usize>() } fn main() { let s = include_str!("inp.txt"); - println!("{}", unsafe { part2(s) }); + println!("{}", unsafe { run(s) }); // dbg!(exec(&program, regi)); } #[bench] fn benc(b: &mut test::Bencher) { let i = boxd(include_str!("inp.txt")); - b.iter(|| part2(i)); + b.iter(|| unsafe { run(i) }); } |