From adb0e84858569373c8e27acb644a2f3dce38b2bf Mon Sep 17 00:00:00 2001 From: kageru Date: Thu, 8 Jul 2021 23:58:57 +0200 Subject: [PATCH] caching meme for D17 to save time --- 2020/src/grid/position.rs | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/2020/src/grid/position.rs b/2020/src/grid/position.rs index 5823cd2..a995765 100644 --- a/2020/src/grid/position.rs +++ b/2020/src/grid/position.rs @@ -1,5 +1,6 @@ extern crate test; use super::direction::*; +use lazy_static::lazy_static; use std::{ convert::TryInto, hash::Hash, ops::{Add, Mul, Sub} }; @@ -55,6 +56,40 @@ impl PositionND { pub fn neighbors(&self) -> [PositionND; num_neighbors(DIMS)] where [PositionND; num_neighbors(DIMS) + 1]: Sized { + // Day 17 gets 25% faster if we cheat by using these cached vectors + if DIMS < 5 { + return match DIMS { + 1 => { + let mut out = [*self; num_neighbors(DIMS)]; + for (out, dir) in out.iter_mut().zip(NEIGHBOR_VECTORS_1D.iter()) { + *out = *out + PositionND::from_padded(dir); + } + out + } + 2 => { + let mut out = [*self; num_neighbors(DIMS)]; + for (out, dir) in out.iter_mut().zip(NEIGHBOR_VECTORS_2D.iter()) { + *out = *out + PositionND::from_padded(dir); + } + out + } + 3 => { + let mut out = [*self; num_neighbors(DIMS)]; + for (out, dir) in out.iter_mut().zip(NEIGHBOR_VECTORS_3D.iter()) { + *out = *out + PositionND::from_padded(dir); + } + out + } + 4 => { + let mut out = [*self; num_neighbors(DIMS)]; + for (out, dir) in out.iter_mut().zip(NEIGHBOR_VECTORS_4D.iter()) { + *out = *out + PositionND::from_padded(dir); + } + out + } + _ => unreachable!(), + }; + } let ns = neighbor_vectors::(); let mut out = [*self; num_neighbors(DIMS)]; for (out, dir) in out.iter_mut().zip(IntoIterator::into_iter(ns).filter(|n| n != &[0; DIMS])) { @@ -64,6 +99,18 @@ impl PositionND { } } +fn build_neighbor_cache() -> Vec<[i64; D]> +where [(); num_neighbors(D) + 1]: { + IntoIterator::into_iter(neighbor_vectors::()).filter(|n| n != &[0; D]).collect() +} + +lazy_static! { + static ref NEIGHBOR_VECTORS_1D: Vec<[i64; 1]> = build_neighbor_cache::<1>(); + static ref NEIGHBOR_VECTORS_2D: Vec<[i64; 2]> = build_neighbor_cache::<2>(); + static ref NEIGHBOR_VECTORS_3D: Vec<[i64; 3]> = build_neighbor_cache::<3>(); + static ref NEIGHBOR_VECTORS_4D: Vec<[i64; 4]> = build_neighbor_cache::<4>(); +} + #[macro_export] macro_rules! dim { ($d: expr) => {{