Skip to content

Commit

Permalink
more implementations of d5p1
Browse files Browse the repository at this point in the history
  • Loading branch information
SOF3 committed Dec 7, 2024
1 parent 104913c commit e5811a3
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 34 deletions.
4 changes: 3 additions & 1 deletion src/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
}
8 changes: 4 additions & 4 deletions src/all/d4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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] {
Expand Down
94 changes: 65 additions & 29 deletions src/all/d5.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::BTreeSet;
use std::collections::{BTreeSet, HashSet};
use std::hash::BuildHasher;

use rustc_hash::{FxHashMap, FxHashSet};

Expand All @@ -7,13 +8,13 @@ use crate::Parse;
#[derive(Clone)]
pub struct Input {
constraints: Vec<Constraint>,
updates: Vec<Update>,
updates: Vec<Update>,
}

#[derive(Clone)]
struct Constraint {
earlier: u32,
later: u32,
later: u32,
}

#[derive(Clone)]
Expand All @@ -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 {
Expand All @@ -47,56 +51,88 @@ impl Parse for Input {
}
}

pub fn p1_fxhash(input: Input) -> u32 {
let mut deny_lists: FxHashMap<u32, Vec<u32>> = 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<Item = u32>;
}

let mut result = 0;
#[derive(Default)]
struct FxHashMapDenyLists(FxHashMap<u32, Vec<u32>>);

'update: for Update(items) in input.updates {
let mut disallowed: FxHashSet<u32> = 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<Item = u32> {
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<Item = u32> {
self.0.range((later, 0)..=(later, u32::MAX)).map(|&(_, earlier)| earlier)
}
}

result
trait DisallowedSet: Default + Extend<u32> {
fn contains(&self, item: u32) -> bool;

fn clear(&mut self);
}

impl<S: BuildHasher + Default> DisallowedSet for HashSet<u32, S> {
fn contains(&self, item: u32) -> bool { HashSet::contains(self, &item) }

fn clear(&mut self) { HashSet::clear(self); }
}

impl DisallowedSet for Vec<u32> {
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<DenyListsT: DenyLists, DisallowedSetT: DisallowedSet>(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<u32> = 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::<FxHashMapDenyLists, FxHashSet<u32>>(input)
}

pub fn p1_btreemap_fxhashset(input: Input) -> u32 { p1::<BTreeSetDenyLists, FxHashSet<u32>>(input) }

pub fn p1_fxhashmap_vec(input: Input) -> u32 { p1::<FxHashMapDenyLists, Vec<u32>>(input) }

pub fn p1_btreemap_vec(input: Input) -> u32 { p1::<BTreeSetDenyLists, Vec<u32>>(input) }

0 comments on commit e5811a3

Please sign in to comment.