Rust Day 3 Part 2
This commit is contained in:
parent
01ba0f9ffb
commit
d3430aa432
3 changed files with 70 additions and 12 deletions
2
rust/Cargo.lock
generated
2
rust/Cargo.lock
generated
|
@ -4,4 +4,4 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "advent-of-code"
|
name = "advent-of-code"
|
||||||
version = "23.3.1"
|
version = "23.3.2"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "advent-of-code"
|
name = "advent-of-code"
|
||||||
version = "23.3.1"
|
version = "23.3.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
default-run = "day03"
|
default-run = "day03"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,69 @@
|
||||||
pub(crate) fn part_2(_input: &'static str) -> u64 {
|
use std::collections::HashMap;
|
||||||
todo!("Part 2")
|
|
||||||
|
#[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)]
|
#[cfg(test)]
|
||||||
|
@ -8,17 +72,11 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_with_sample_solution() {
|
fn test_with_sample_solution() {
|
||||||
assert_eq!(
|
assert_eq!(super::part_2(SAMPLE_INPUT), 467835);
|
||||||
super::part_2(SAMPLE_INPUT),
|
|
||||||
todo!("Add result from example part 2")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_with_solution() {
|
fn test_with_solution() {
|
||||||
assert_eq!(
|
assert_eq!(super::part_2(crate::INPUT), 80703636);
|
||||||
super::part_2(crate::INPUT),
|
|
||||||
todo!("Add result for solved part 2")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue