This commit is contained in:
nora 2023-12-03 15:45:36 +01:00
parent d47ca1f175
commit d08e7d8c7c
3 changed files with 75 additions and 1 deletions

View file

@ -1,6 +1,7 @@
mod p2basic; mod p2basic;
mod p2faster_hash; mod p2faster_hash;
mod p2less_alloc; mod p2less_alloc;
mod p2less_with_capacity;
use helper::Day; use helper::Day;
@ -18,6 +19,7 @@ helper::define_variants! {
part2 { part2 {
basic => crate::p2basic::part2; basic => crate::p2basic::part2;
faster_hash => crate::p2faster_hash::part2; faster_hash => crate::p2faster_hash::part2;
p2less_with_capacity => crate::p2less_with_capacity::part2;
less_alloc => crate::p2less_alloc::part2; less_alloc => crate::p2less_alloc::part2;
} }
} }

View file

@ -1,3 +1,5 @@
use std::hash::BuildHasherDefault;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
/// States: /// States:
@ -58,7 +60,8 @@ pub fn part2(input: &str) -> u64 {
let mut prev2 = empty_border.as_str(); let mut prev2 = empty_border.as_str();
let mut prev1 = input.lines().next().unwrap(); let mut prev1 = input.lines().next().unwrap();
let mut gears: FxHashMap<u32, GearRatio> = FxHashMap::default(); let mut gears: FxHashMap<u32, GearRatio> =
FxHashMap::with_capacity_and_hasher(1000, BuildHasherDefault::default());
for (line_number, next) in input for (line_number, next) in input
.lines() .lines()

View file

@ -0,0 +1,69 @@
use std::hash::BuildHasherDefault;
use rustc_hash::FxHashMap;
pub fn part2(input: &str) -> u64 {
fn contains_gear(s: &str) -> Option<usize> {
s.chars().position(|c| !c.is_ascii_digit() && c != '.')
}
let len = input.lines().next().unwrap().len();
let empty_border = std::iter::repeat('.').take(len).collect::<String>();
let mut prev2 = empty_border.as_str();
let mut prev1 = input.lines().next().unwrap();
let mut gears: FxHashMap<u32, Vec<u64>> =
FxHashMap::with_capacity_and_hasher(1000, BuildHasherDefault::default());
for (line_number, next) in input
.lines()
.skip(1)
.chain(Some(empty_border.as_str()))
.enumerate()
{
let mut numbers = prev1.char_indices().peekable();
while let Some((start, c)) = numbers.next() {
if c.is_ascii_digit() {
let mut end = start;
while let Some((idx, '0'..='9')) = numbers.next() {
end = idx;
}
let box_bounds = (start.saturating_sub(1))..std::cmp::min(end + 2, len);
let number = prev1[start..=end].parse::<u64>().unwrap();
let mut push = |key: (usize, usize)| {
gears
.entry(((key.1 as u32) << 16) | (key.0 as u32))
.or_default()
.push(number)
};
if let Some(position) = contains_gear(&prev2[box_bounds.clone()]) {
let key = (line_number - 1, box_bounds.start + position);
push(key);
}
if let Some(position) = contains_gear(&prev1[box_bounds.clone()]) {
let key = (line_number, box_bounds.start + position);
push(key);
}
if let Some(position) = contains_gear(&next[box_bounds.clone()]) {
let key = (line_number + 1, box_bounds.start + position);
push(key);
}
}
}
prev2 = prev1;
prev1 = next;
}
gears
.values()
.filter(|v| v.len() == 2)
.map(|v| v[0] * v[1])
.sum()
}