Rust Day 3 Part 2

This commit is contained in:
Tobias Berger 2023-12-03 11:25:49 +01:00
parent 01ba0f9ffb
commit d3430aa432
Signed by: toby
GPG key ID: 2D05EFAB764D6A88
3 changed files with 70 additions and 12 deletions

2
rust/Cargo.lock generated
View file

@ -4,4 +4,4 @@ version = 3
[[package]]
name = "advent-of-code"
version = "23.3.1"
version = "23.3.2"

View file

@ -1,6 +1,6 @@
[package]
name = "advent-of-code"
version = "23.3.1"
version = "23.3.2"
edition = "2021"
default-run = "day03"

View file

@ -1,5 +1,69 @@
pub(crate) fn part_2(_input: &'static str) -> u64 {
todo!("Part 2")
use std::collections::HashMap;
#[derive(Debug)]
struct PartNumber {
number: u64,
adjacent_gear: usize,
}
pub(crate) fn part_2(input: &'static str) -> u64 {
let mut part_numbers = vec![];
for (y, line) in input.lines().enumerate() {
let mut search_index = 0;
loop {
let search_line = &line[search_index..];
if search_line.is_empty() {
break;
}
let Some(number_start) = search_line.find(|c| char::is_ascii_digit(&c)) else {
break;
};
let number_end = search_line[number_start..]
.find(|c| !char::is_ascii_digit(&c))
.unwrap_or(search_line.len() - number_start)
+ number_start;
let number = search_line[number_start..number_end]
.parse()
.expect("Should be a valid number");
let mut gears = vec![];
// This `line.len()` assumes the input is square
for y in y.saturating_sub(1)..=usize::min(y + 1, line.len() - 1) {
for x in (search_index + number_start).saturating_sub(1)
..=usize::min(search_index + number_end, line.len())
{
let idx = y * (line.len() + 1) + x;
let char = input.as_bytes()[idx] as char;
if matches!(char, '*') {
gears.push(idx)
}
}
}
part_numbers.extend(gears.iter().map(|&gear| PartNumber {
number,
adjacent_gear: gear,
}));
search_index += number_end;
}
}
let mut groups = HashMap::new();
for part_number in part_numbers {
let Some(group) = groups.get_mut(&part_number.adjacent_gear) else {
groups.insert(part_number.adjacent_gear, vec![part_number]);
continue;
};
group.push(part_number);
}
groups
.values()
.filter(|group| group.len() == 2)
.map(|group| group[0].number * group[1].number)
.sum()
}
#[cfg(test)]
@ -8,17 +72,11 @@ mod tests {
#[test]
fn test_with_sample_solution() {
assert_eq!(
super::part_2(SAMPLE_INPUT),
todo!("Add result from example part 2")
);
assert_eq!(super::part_2(SAMPLE_INPUT), 467835);
}
#[test]
fn test_with_solution() {
assert_eq!(
super::part_2(crate::INPUT),
todo!("Add result for solved part 2")
);
assert_eq!(super::part_2(crate::INPUT), 80703636);
}
}