diff --git a/2023/day03/src/lib.rs b/2023/day03/src/lib.rs index 6bc38ac..c5df13c 100644 --- a/2023/day03/src/lib.rs +++ b/2023/day03/src/lib.rs @@ -1,6 +1,5 @@ mod p2faster_hash; - -use std::collections::HashMap; +mod p2basic; use helper::Day; @@ -16,7 +15,7 @@ helper::define_variants! { basic => crate::part1; } part2 { - basic => crate::part2; + basic => crate::p2basic::part2; fasher_hash => crate::p2faster_hash::part2; } } @@ -72,63 +71,6 @@ fn part1(input: &str) -> u64 { acc } -fn part2(input: &str) -> u64 { - fn contains_gear(s: &str) -> Option { - 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::(); - - let mut prev2 = empty_border.as_str(); - let mut prev1 = input.lines().next().unwrap(); - - let mut gears: HashMap<(usize, usize), Vec> = HashMap::new(); - - 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::().unwrap(); - - if let Some(position) = contains_gear(&prev2[box_bounds.clone()]) { - let key = (line_number - 1, box_bounds.start + position); - gears.entry(key).or_default().push(number); - } - - if let Some(position) = contains_gear(&prev1[box_bounds.clone()]) { - let key = (line_number, box_bounds.start + position); - gears.entry(key).or_default().push(number); - } - - if let Some(position) = contains_gear(&next[box_bounds.clone()]) { - let key = (line_number + 1, box_bounds.start + position); - gears.entry(key).or_default().push(number); - } - } - } - - prev2 = prev1; - prev1 = next; - } - - gears - .values() - .filter(|v| v.len() == 2) - .map(|v| v[0] * v[1]) - .sum() -} helper::tests! { day03 Day03; diff --git a/2023/day03/src/p2basic.rs b/2023/day03/src/p2basic.rs new file mode 100644 index 0000000..c02a420 --- /dev/null +++ b/2023/day03/src/p2basic.rs @@ -0,0 +1,59 @@ +use std::collections::HashMap; + +pub fn part2(input: &str) -> u64 { + fn contains_gear(s: &str) -> Option { + 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::(); + + let mut prev2 = empty_border.as_str(); + let mut prev1 = input.lines().next().unwrap(); + + let mut gears: HashMap<(usize, usize), Vec> = HashMap::new(); + + 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::().unwrap(); + + if let Some(position) = contains_gear(&prev2[box_bounds.clone()]) { + let key = (line_number - 1, box_bounds.start + position); + gears.entry(key).or_default().push(number); + } + + if let Some(position) = contains_gear(&prev1[box_bounds.clone()]) { + let key = (line_number, box_bounds.start + position); + gears.entry(key).or_default().push(number); + } + + if let Some(position) = contains_gear(&next[box_bounds.clone()]) { + let key = (line_number + 1, box_bounds.start + position); + gears.entry(key).or_default().push(number); + } + } + } + + prev2 = prev1; + prev1 = next; + } + + gears + .values() + .filter(|v| v.len() == 2) + .map(|v| v[0] * v[1]) + .sum() +}