heh
| -rw-r--r-- | src/main.rs | 304 |
1 files changed, 101 insertions, 203 deletions
diff --git a/src/main.rs b/src/main.rs index fc39b79..b72f4e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ redundant_semicolons )] #![feature( + int_lowest_highest_one, const_cmp, int_roundings, type_alias_impl_trait, @@ -71,227 +72,124 @@ use std::{ }; use swizzle::array; pub use util::prelude::*; +use z3::ast::Int; mod rah; use atools::prelude::*; use crate::util::UnionFind; #[unsafe(no_mangle)] #[implicit_fn::implicit_fn] -pub unsafe fn p1(x: &'static [u8]) -> impl Debug { - let p = util::uints::<i64>(x) - .array_chunks::<2>() - .collect::<Vec<_>>(); - let mut i = fimg::Image::<_, 1>::alloc( - p.iter().map(|[x, _]| *x).max().unwrap() as u32 / 12, - p.iter().map(|[_, x]| *x).max().unwrap() as u32 / 12, - ); - i.points( - &p.iter() - .map(|[a, b]| (*a as i32 / 12, *b as i32 / 12)) - .collect::<Vec<_>>(), - [255], - ); - i.points( - &[ - (98278 / 12, 50283 / 12), - (98278 / 12, 4250 / 12), - (63518 / 12, 4250 / 12), - (63518 / 12, 50283 / 12), - (98278 / 12, 50283 / 12), - ], - [129], - ); - i.save("hm.png"); - i.show(); - return p - .into_iter() - .array_combinations() - .map_w(|z @ [[x1, y1], [x2, y2]]| { - // dbg!(z); - ((x2 - x1 - 1).abs() * (y2 - y1 - 1).abs()) - }) - .max_by_key(|x| x.1) - .unwrap(); -} - -pub(crate) fn sq(p1: [i64; 3], p2: [i64; 3]) -> i64 { - (p1[0] - p2[0]).pow(2) + (p1[1] - p2[1]).pow(2) + (p1[2] - p2[2]).pow(2) -} - -#[unsafe(no_mangle)] -pub(crate) unsafe fn p2(x: &[u8]) -> i64 { - let mut p = x.as_ptr(); - let end = p.add(x.len()); - - static mut points: [[i32; 1000]; 3] = [[0; 1000]; 3]; - let mut i = 0; - while p != end { - let mut f = |til| { - let mut rest = 0; - while let x = p.λ() - && x != til - { - rest *= 10; - rest += (x - b'0') as i32; +pub unsafe fn p1(x: &'static [u8; ISIZE]) -> impl Debug { + let x = x + .行() + .map(|x| { + let (expected, buttons) = x.μ(' '); + let mut c = vec![]; + let mut r = vec![]; + let (mut buttons, power) = buttons.rsplit_once(|x| *x == b' ').unwrap(); + + while let Some(x) = buttons.get(0) { + match x { + b'(' => {} + d @ b'0'..=b'9' => c.push(d - b'0'), + b',' => {} + b')' => { + r.push(c.clone()); + c.clear(); + } + b' ' => {} + x => panic!("{}", *x as char), + } + buttons = &buttons[1..]; } - rest - }; - let x = f(b','); - let y = f(b','); - let z = f(b'\n'); - (points[0][i], points[1][i], points[2][i]) = (x, y, z); - i += 1; - } - (281..955) - .map(|i| { - // let former = from_fn(|j| points[j][i] as i64); - // let (_dist, _retval) = (0..1000) - // .filter(|j| i != *j) - // .filter_map(|j| { - // let with: [i64; 3] = from_fn(|i| points[i][j] as i64); - // let d = sq(former, from_fn(|i| points[i][j] as i64)) as i64; - // // println!("{former:?} <-> {with:?}: {d}"); - // Some((d, points[0][i] as i64 * points[0][j] as i64)) - // }) - // .min_by_key(|&(d, _)| d) - // .unwrap_or((i64::MAX, 0)); - // dbg!(_dist); - - let [_x, _y, _z] = from_fn(|j| points[j][i]); - let x = i32x8::splat(_x); - let y = i32x8::splat(_y); - let z = i32x8::splat(_z); - // result of min distance - let mut dist = i64x8::splat(i64::MAX); - // result of the multiply - let mut retval = Simd::splat(0); - let [(x_, xrest), (y_, yrest), (z_, zrest)] = { - [ - points[0][25..905].as_chunks::<8>(), - points[1][25..905].as_chunks::<8>(), - points[2][25..905].as_chunks::<8>(), - ] - }; - // let mut rmin = [i64::MAX; 16]; - // let mut reduced = i64::MAX; - for (x_, y_, z_) in izip!(x_, y_, z_) { - let x_ = Simd::from_slice(x_); - let y_ = Simd::from_slice(y_); - let z_ = Simd::from_slice(z_); - let one = (x - x_).cast::<i64>(); - let two = (y - y_).cast::<i64>(); - let thr = (z - z_).cast::<i64>(); - let d = one * one + two * two + thr * thr; - // let min = izip!(x_.to_array(), y_.to_array(), z_.to_array()) - // .map(|(x, y, z)| { - // sq( - // [x as i64, y as i64, z as i64], - // [_x as i64, _y as i64, _z as i64], - // ) - // }) - // .collect_array::<16>() - // .unwrap(); - // rmin = min - // .zip(rmin) - // .map(|(x, y)| if x.min(y) == 0 { y } else { x.min(y) }); - - // dbg!(d); - let m = d.simd_lt(dist) & d.simd_ne(Simd::splat(0)); - // dbg!(d); - // reduced = reduced.min(m.select(d, Simd::splat(i64::MAX)).reduce_min()); - // min_by_key ( distance ) - dist = m.select(d, dist); - // println!("{rmin:?} {dist:?}"); - // assert_eq!(rmin, dist.to_array()); - // dbg!(dist); - - // points[0][1] * points[1][0] - retval = m.select(x.cast::<i64>() * x_.cast::<i64>(), retval); - } - // dbg!(rmin, reduced); - - // let (dist_, retval_) = izip!(xrest, yrest, zrest) - // .filter_map(|t| { - // let d = sq( - // [_x as i64, _y as i64, _z as i64], - // <[_; 3]>::from(t).map(|x| *x as i64), - // ); - // Some((d, _x as i64 * *t.0 as i64)) - // }) - // // .chain(izip!(dist.to_array(), retval.to_array())) - // .min_by_key(|&(d, _)| d) - // .unwrap(); - // dbg!(dist, retval, dist_, _retval); - - (dist, retval) - // todo x8? - // let dist = dist - // .to_array() - // .into_iter() - // .zip(retval.to_array()) - // .min_by_key(|x| x.0) - // .unwrap(); - // let rest = retval; - // let (dist, retval) = izip!(xrest, yrest, zrest) - // .filter_map(|t| { - // let d = sq( - // [_x as i64, _y as i64, _z as i64], - // <[_; 3]>::from(t).map(|x| *x as i64), - // ) as i64; - // Some((d, _x as i64 * *t.0 as i64)) - // }) - // .chain(izip!(dist.to_array(), retval.to_array())) - // .filter(|(d, _)| *d != 0) - // .min_by_key(|&(d, _)| d) - // .unwrap(); - // println!("{i}"); - // assert_eq!(dist, _dist); - // assert_eq!(retval, _retval); - // println!("pass"); - // (dist, retval) - }) - .fold((-1, 0), |(_scdist, _scretval), (dist, retval)| { - // we do a lil maxxing - // eprintln!("dist = {dist:?}\nretval = {retval:?}\n_dist = {_dist:?}\n_retval = {_retval:?}"); - let (scdist, scretval) = dist - .to_array() - .into_iter() - .zip(retval.to_array()) - .min_by_key(|x| x.0) - .unwrap(); - // eprintln!("min of new {scdist} {scretval}"); - // let m = Simd::splat(dbg!(dist.reduce_min().max(scdist))).simd_ge(_dist); - // eprintln!("{} >= {_dist:?} {m:?}", dist.reduce_min()); - // eprintln!("dmatched = {:?}",m.select(dist, Simd::splat(0))); - // eprintln!("rmatched = {:?}",m.select(retval, Simd::splat(0))); - // dbg!(real); - - if scdist > _scdist { - (scdist, scretval) - } else { - (_scdist, _scretval) + let mut power = &power[1..]; + let mut pvec = vec![]; + let mut c = 0; + while let Some(x) = power.get(0) { + match x { + d @ b'0'..=b'9' => { + c *= 10; + c += (d - b'0') as i16 + } + b',' => { + pvec.push(c); + c = 0; + } + b'}' => { + pvec.push(c); + break; + } + b' ' => {} + x => panic!("{}", *x as char), + } + power = &power[1..]; } - // m.select(dist, _dist), - // m.select(retval, _retval), - // if dist > mxd {} + ( + expected[1..expected.len() - 1] + .iter() + .map(|x| *x == b'#') + .collect::<Vec<_>>(), + r, + pvec, + ) }) - .1 - - // .reduce_min() + .collect::<Vec<_>>(); + let mut sum = 0; + for (xpected, buttons, power) in x { + let o = z3::Optimize::new(); + let p = (0..buttons.len()) + .map(|_| Int::fresh_const("p")) + .inspect(|x| o.assert(&x.ge(0))) + .collect::<Vec<_>>(); + for j in 0..power.len() { + let sat = &buttons + .iter() + .enumerate() + .filter(|(_, b)| b.contains(&(j as u8))) + .map(|(x, _)| p[x].clone()) + .reduce(|a, b| a + b) + .unwrap() + .eq(power[j]); + o.assert(sat); + } + let s = p.iter().cloned().reduce(|a, b| a + b).unwrap(); + o.minimize(&s); + assert_eq!(o.check(&[]), z3::SatResult::Sat); + let m = o.get_model().unwrap(); + sum += m.eval(&s, true).unwrap().as_i64().unwrap(); + + // sum += util::dijkstra( + // (vec![false; xpected.len()], 0), + // |(x, p)| { + // buttons.iter().map(move |button| { + // let mut new_state = x.clone(); + // for lem in button { + // let p = &mut new_state[*lem as usize]; + // *p = !*p; + // } + // ((new_state, p + 1), p) + // }) + // }, + // |(x, _)| x == &xpected, + // ) + // .unwrap() + // .1 + // .1; + } + sum } - pub(crate) const ISIZE: usize = include_bytes!("inp.txt").len(); pub(crate) fn main() { // dbg!(sq([75262, 24842, 97390], [69492, 23068, 98918])); use atools::prelude::*; - unsafe { println!("{:?}", p1(include_bytes!("../input_day_9"))) }; + unsafe { println!("{:?}", p1(include_bytes!("inp.txt"))) }; // 1550760868 // unsafe { println!("{:?}", p2(include_bytes!("inp.txt"))) }; - // unsafe { println!("{:?}", p2(include_bytes!("../1"))) }; // 3200955921 - // unsafe { println!("{:?}", p2(include_bytes!("../2"))) }; // 8141888143 - // unsafe { println!("{:?}", p2(include_bytes!("../3"))) }; // 8465902405 + // unsafe { println!("{:?}", rah::run(include_bytes!("../1")) == 1644094530) }; // 1644094530 + // unsafe { println!("{:?}", rah::run(include_bytes!("../2")) == 1501292304) }; // 1501292304 + // unsafe { println!("{:?}", rah::run(include_bytes!("../3")) == 1429075575) }; // 1429075575 } #[bench] |