From e5811a375afd1507fdf1cd5d492270944b63b6e0 Mon Sep 17 00:00:00 2001 From: SOFe Date: Sat, 7 Dec 2024 18:06:35 +0800 Subject: [PATCH] more implementations of d5p1 --- src/all.rs | 4 ++- src/all/d4.rs | 8 ++--- src/all/d5.rs | 94 +++++++++++++++++++++++++++++++++++---------------- 3 files changed, 72 insertions(+), 34 deletions(-) diff --git a/src/all.rs b/src/all.rs index 678d073..f7540f2 100644 --- a/src/all.rs +++ b/src/all.rs @@ -226,8 +226,10 @@ main! { } day 5 { part 1 { - "fxhash" => d5::p1_fxhash, + "fxhashmap-fxhashset" => d5::p1_fxhashmap_fxhashset, "btreemap-fxhashset" => d5::p1_btreemap_fxhashset, + "fxhashmap-vec" => d5::p1_fxhashmap_vec, + "btreemap-vec" => d5::p1_btreemap_vec, } } } diff --git a/src/all/d4.rs b/src/all/d4.rs index 23953bd..68f5c42 100644 --- a/src/all/d4.rs +++ b/src/all/d4.rs @@ -10,8 +10,7 @@ pub fn p1_brute(input: String) -> u32 { for (index, _) in input.match_indices('X') { let loc = grid.index_to_loc(index).unwrap(); for &dir in DirectBoth::ALL { - let mut iter = - loc.direct_iter(dir, grid).skip(1).take(3).map(|loc| grid.get(loc)); + let mut iter = loc.direct_iter(dir, grid).skip(1).take(3).map(|loc| grid.get(loc)); let chars: [_; 3] = array::from_fn(|_| iter.next().flatten()); if chars == [Some(b'M'), Some(b'A'), Some(b'S')] { count += 1; @@ -32,8 +31,9 @@ pub fn p2_brute(input: String) -> u32 { let matched = [ [DirectDiagonal::LeftUp, DirectDiagonal::RightDown], [DirectDiagonal::RightUp, DirectDiagonal::LeftDown], - ].map(|ends| { - let values = ends .map(|direct| grid.get(loc.direct(direct, grid)?)); + ] + .map(|ends| { + let values = ends.map(|direct| grid.get(loc.direct(direct, grid)?)); values == [Some(b'M'), Some(b'S')] || values == [Some(b'S'), Some(b'M')] }); if matched[0] && matched[1] { diff --git a/src/all/d5.rs b/src/all/d5.rs index e1488e6..04ba489 100644 --- a/src/all/d5.rs +++ b/src/all/d5.rs @@ -1,4 +1,5 @@ -use std::collections::BTreeSet; +use std::collections::{BTreeSet, HashSet}; +use std::hash::BuildHasher; use rustc_hash::{FxHashMap, FxHashSet}; @@ -7,13 +8,13 @@ use crate::Parse; #[derive(Clone)] pub struct Input { constraints: Vec, - updates: Vec, + updates: Vec, } #[derive(Clone)] struct Constraint { earlier: u32, - later: u32, + later: u32, } #[derive(Clone)] @@ -32,7 +33,10 @@ impl Parse for Input { } let (left, right) = line.split_once('|').unwrap(); - constraints.push(Constraint { earlier: left.parse().unwrap(), later: right.parse().unwrap() }); + constraints.push(Constraint { + earlier: left.parse().unwrap(), + later: right.parse().unwrap(), + }); } for line in lines { @@ -47,56 +51,88 @@ impl Parse for Input { } } -pub fn p1_fxhash(input: Input) -> u32 { - let mut deny_lists: FxHashMap> = FxHashMap::default(); +trait DenyLists: Default { + fn insert(&mut self, later: u32, earlier: u32); - for constraint in input.constraints { - deny_lists.entry(constraint.later).or_default().push(constraint.earlier); - } + fn get_earlier_items(&self, later: u32) -> impl Iterator; +} - let mut result = 0; +#[derive(Default)] +struct FxHashMapDenyLists(FxHashMap>); - 'update: for Update(items) in input.updates { - let mut disallowed: FxHashSet = FxHashSet::default(); +impl DenyLists for FxHashMapDenyLists { + fn insert(&mut self, later: u32, earlier: u32) { + self.0.entry(later).or_default().push(earlier); + } - for &item in &items { - if disallowed.contains(&item) { - continue 'update; - } + fn get_earlier_items(&self, later: u32) -> impl Iterator { + self.0.get(&later).into_iter().flatten().copied() + } +} - if let Some(deny_list) = deny_lists.get(&item) { - disallowed.extend(deny_list); - } - } +#[derive(Default)] +struct BTreeSetDenyLists(BTreeSet<(u32, u32)>); + +impl DenyLists for BTreeSetDenyLists { + fn insert(&mut self, later: u32, earlier: u32) { self.0.insert((later, earlier)); } - result+=items[items.len()/2]; + fn get_earlier_items(&self, later: u32) -> impl Iterator { + self.0.range((later, 0)..=(later, u32::MAX)).map(|&(_, earlier)| earlier) } +} - result +trait DisallowedSet: Default + Extend { + fn contains(&self, item: u32) -> bool; + + fn clear(&mut self); +} + +impl DisallowedSet for HashSet { + fn contains(&self, item: u32) -> bool { HashSet::contains(self, &item) } + + fn clear(&mut self) { HashSet::clear(self); } +} + +impl DisallowedSet for Vec { + fn contains(&self, item: u32) -> bool { self.iter().any(|&v| v == item) } + + fn clear(&mut self) { Vec::clear(self); } } -pub fn p1_btreemap_fxhashset(input: Input) -> u32 { - let mut deny_lists: BTreeSet<(u32, u32)> = BTreeSet::default(); +fn p1(input: Input) -> u32 { + let mut deny_lists = DenyListsT::default(); for constraint in input.constraints { - deny_lists.insert((constraint.later, constraint.earlier)); + deny_lists.insert(constraint.later, constraint.earlier); } let mut result = 0; + let mut disallowed = DisallowedSetT::default(); + 'update: for Update(items) in input.updates { - let mut disallowed: FxHashSet = FxHashSet::default(); + disallowed.clear(); for &item in &items { - if disallowed.contains(&item) { + if disallowed.contains(item) { continue 'update; } - disallowed.extend(deny_lists.range((item, 0)..=(item, u32::MAX)).map(|&(_, dep)| dep)); + disallowed.extend(deny_lists.get_earlier_items(item)); } - result+=items[items.len()/2]; + result += items[items.len() / 2]; } result } + +pub fn p1_fxhashmap_fxhashset(input: Input) -> u32 { + p1::>(input) +} + +pub fn p1_btreemap_fxhashset(input: Input) -> u32 { p1::>(input) } + +pub fn p1_fxhashmap_vec(input: Input) -> u32 { p1::>(input) } + +pub fn p1_btreemap_vec(input: Input) -> u32 { p1::>(input) }