heh
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 126 |
1 files changed, 13 insertions, 113 deletions
diff --git a/src/main.rs b/src/main.rs index bfa424a..2ba9db6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -69,122 +69,22 @@ pub use util::prelude::*; #[allow(warnings)] type u32x3 = Simd<u32, 3>; - -impl Debug for Item { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{} {:?}", self.name.get(), self.kind) - } -} - -#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] - -struct Item { - name: identifier, - kind: ItemK, -} -#[derive(Clone, Copy, Debug)] -#[repr(u8)] -enum identifier { - u1, - u2, - u3, - u4, - u5, - u6, - u7, - u8, - u9, -} -impl identifier { - fn get(self) -> u8 { - self as u8 - } -} -impl PartialEq for identifier { - fn eq(&self, other: &Self) -> bool { - self.get() == other.get() - } -} -impl Eq for identifier {} -impl PartialOrd for identifier { - fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { - self.get().partial_cmp(&other.get()) - } -} -impl Ord for identifier { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.get().cmp(&other.get()) - } -} -impl Hash for identifier { - fn hash<H: std::hash::Hasher>(&self, state: &mut H) { - self.get().hash(state) - } -} -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -enum ItemK { - Chip, - Gen, -} -use ItemK::*; #[unsafe(no_mangle)] #[implicit_fn::implicit_fn] pub unsafe fn p1(x: &'static [u8; ISIZE]) -> impl Debug { - let re = Regex::new(r"([0-9a-z]+) generator").unwrap(); - let rechip = Regex::new(r"([0-9a-z]+)-compatible microchip").unwrap(); - let mut floors = vec![vec![]; 4]; - x.行().zip(&mut floors).for_each(|(x, to)| { - to.extend(re.captures_iter(x).map(|x| Item { - name: transmute(x.get(1).unwrap().as_bytes()[0] - b'0'), - kind: Gen, - })); - to.extend(rechip.captures_iter(x).map(|x| Item { - name: transmute(x.get(1).unwrap().as_bytes()[0] - b'0'), - kind: Chip, - })); - }); - // if a chip is ever left in the same area as another RTG, and it's not connected to its own RTG, the chip will be fried. - fn not_fried(floor: impl Iterator<Item = Item> + Clone) -> bool { - floor.clone().all(_.kind == Chip) - || floor - .clone() - .filter(_.kind == Chip) // every chip - .all(|x| floor.clone().filter(_.kind == Gen).any(_.name == x.name)) // is connected - }; - - util::steps_astar( - (0, floors), - |(e, floor)| { - [(e < 3).then(|| e + 1), (e > 0).then(|| e - 1)] - .into_iter() - .flatten() - .flat_map(move |v| { - floor[e] - .clone() - .into_iter() - .ι() - .tuple_combinations() - .map(|(a, b)| vec![a, b]) - .chain(floor[e].clone().into_iter().ι().map(|a| vec![a])) - .map({ - let floor = floor.clone(); - move |mut x| { - let mut floor = floor.clone(); - floor[v].extend(x.iter().map(|x| x.0)); - x.sort_by_key(|x| x.1); - x.iter().rev().map(|(_, i)| floor[e].swap_remove(*i)).θ(); - floor[v].sort(); - floor[e].sort(); - (v, floor) - } - }) - }) - .filter(|(e, floor)| not_fried(floor[*e].iter().copied())) - .map(|n| (n, 1)) - }, - |x| -(x.1[3].len() as i16), - |(_, f)| f[0..3].iter().all(_.is_empty()), - ) + let mut store = Vec::with_capacity(1024); + store.push(1); + (1..) + .map(|x| { + util::nb(spiral::coordinate_of(x)) + .map(spiral::index_at) + .iter() + .flat_map(|x| store.get(*x as usize)) + .sum::<u32>() + .and(|&x| store.push(x)) + }) + .find(|x| *x > 325489) + // util::manhattan((-285, -267), (0, 0)) } const ISIZE: usize = include_bytes!("inp.txt").len(); fn main() { |