heh
Diffstat (limited to 'src/util.rs')
| -rw-r--r-- | src/util.rs | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/src/util.rs b/src/util.rs index 41a6afa..40993d8 100644 --- a/src/util.rs +++ b/src/util.rs @@ -222,32 +222,59 @@ impl<T, E> UnsoundUtilities<T> for Result<T, E> { } } -pub struct LMap<K, V, F>(HashMap<K, V>, F) +pub struct LMap<K, V>(HashMap<K, V>, fn(K) -> V) where - F: Fn(K) -> Option<V>, K: Eq + Hash + Copy; -impl<K: Eq + Hash + Copy, V, F> LMap<K, V, F> -where - F: Fn(K) -> Option<V>, -{ - pub fn new(f: F) -> Self { +impl<K: Ord + Eq + Debug + Hash + Copy, V: Copy + Debug> LMap<K, V> { + pub fn new(f: fn(K) -> V) -> Self { Self { 0: HashMap::default(), 1: f, } } - pub fn get(&mut self, k: K) -> Option<&mut V> { - match self.0.entry(k) { - Entry::Occupied(x) => Some(x.into_mut()), - Entry::Vacant(e) => match self.1(k) { - Some(v) => Some(e.insert(v)), - None => None, - }, + pub fn with_cap(f: fn(K) -> V, cap: usize) -> Self { + Self { + 0: HashMap::with_capacity_and_hasher(cap, rustc_hash::FxBuildHasher::default()), + 1: f, } } + + pub fn get(&mut self, k: K) -> V { + if let Some(x) = self.0.get(&k) { + return *x; + } + // let mut ks = self.0.keys().collect::<Vec<_>>(); + // ks.sort(); + // println!("{ks:?}"); + let elm = self.1(k); + self.0.insert(k, elm); + elm + } } +macro_rules! memoize { + (|$pat:pat_param in $in:ty| -> $out:ty $body:block; $arg:expr) => {{ + static mut MEMOIZER: std::sync::OnceLock<crate::util::LMap<$in, $out>> = + std::sync::OnceLock::new(); + unsafe { + MEMOIZER.get_mut_or_init(|| crate::util::LMap::new(|$pat: $in| -> $out { $body })) + } + .get($arg) + }}; + (|$pat:pat_param in $in:ty| -> $out:ty $body:block; $arg:expr; with cap $cap:literal) => {{ + static mut MEMOIZER: std::sync::OnceLock<crate::util::LMap<$in, $out>> = + std::sync::OnceLock::new(); + unsafe { + MEMOIZER.get_mut_or_init(|| { + crate::util::LMap::with_cap(|$pat: $in| -> $out { $body }, $cap) + }) + } + .get($arg) + }}; +} +pub(crate) use memoize; + pub fn countg_with_check<N: Debug + PartialEq + Hash + Eq + Copy, I: Iterator<Item = N>>( start: N, graph: &mut impl Fn(N) -> I, @@ -638,6 +665,12 @@ impl DigiCount for u8 { } } +impl DigiCount for u128 { + fn ͱ(self) -> u32 { + self.checked_ilog10().ψ() + 1 + } +} + pub trait Ͷ: DigiCount { fn ͷ(self) -> impl Iterator<Item = u8>; fn Ͷ(self, i: u8) -> u8; @@ -656,6 +689,7 @@ macro_rules! digs { } }; } +digs!(u128); digs!(u64); digs!(u32); digs!(u16); |