mirror of
https://github.com/theoludwig/advent_of_code_2023.git
synced 2024-10-29 22:17:19 +01:00
Merge branch 'day-3-part-2'
This commit is contained in:
commit
97c302d9e1
@ -72,6 +72,6 @@ In this schematic, there are **two** gears. The first is in the top left; it has
|
||||
|
||||
**What is the sum of all of the gear ratios in your engine schematic?**
|
||||
|
||||
Your puzzle answer was `answer`.
|
||||
Your puzzle answer was `84363105`.
|
||||
|
||||
**Both parts of this puzzle are complete! They provide two gold stars: `**`.**
|
||||
|
126
day_3/src/lib.rs
126
day_3/src/lib.rs
@ -1,8 +1,17 @@
|
||||
#[derive(Debug, PartialEq)]
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, PartialEq, Default, Clone, Copy)]
|
||||
pub struct GearPosition {
|
||||
pub index_line: usize,
|
||||
pub index_character: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Default, Clone, Copy)]
|
||||
pub struct NumberPosition {
|
||||
pub index_start: usize,
|
||||
pub index_end: usize,
|
||||
pub value: usize,
|
||||
pub gear_position: GearPosition,
|
||||
}
|
||||
|
||||
pub fn get_numbers_positions_from_line(line: &str) -> Vec<NumberPosition> {
|
||||
@ -23,6 +32,7 @@ pub fn get_numbers_positions_from_line(line: &str) -> Vec<NumberPosition> {
|
||||
index_start,
|
||||
index_end,
|
||||
value,
|
||||
gear_position: GearPosition::default(),
|
||||
});
|
||||
number_string = String::from("");
|
||||
index_start = 0;
|
||||
@ -35,6 +45,7 @@ pub fn get_numbers_positions_from_line(line: &str) -> Vec<NumberPosition> {
|
||||
index_start,
|
||||
index_end,
|
||||
value,
|
||||
gear_position: GearPosition::default(),
|
||||
});
|
||||
}
|
||||
result
|
||||
@ -44,6 +55,10 @@ pub fn is_symbol(character: char) -> bool {
|
||||
!character.is_ascii_digit() && character != '.'
|
||||
}
|
||||
|
||||
pub fn is_gear_symbol(character: char) -> bool {
|
||||
character == '*'
|
||||
}
|
||||
|
||||
pub fn part_1(input: &str) -> usize {
|
||||
let lines = input.lines().collect::<Vec<&str>>();
|
||||
lines
|
||||
@ -82,15 +97,108 @@ pub fn part_1(input: &str) -> usize {
|
||||
|| has_symbol_on_the_top
|
||||
|| has_symbol_on_the_bottom
|
||||
})
|
||||
.map(|matching_number| matching_number.value)
|
||||
.map(|number_position| number_position.value)
|
||||
.sum::<usize>()
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
// pub fn part_2(_input: &str) -> usize {
|
||||
// 42
|
||||
// }
|
||||
pub fn part_2(input: &str) -> usize {
|
||||
let lines = input.lines().collect::<Vec<&str>>();
|
||||
let mut number_positions = vec![];
|
||||
|
||||
lines.iter().enumerate().for_each(|(index_line, &line)| {
|
||||
get_numbers_positions_from_line(line)
|
||||
.iter()
|
||||
.for_each(|&number_position| {
|
||||
let index_start = number_position.index_start.saturating_sub(1);
|
||||
let index_end = if number_position.index_end + 1 >= line.len() {
|
||||
line.len().saturating_sub(1)
|
||||
} else {
|
||||
number_position.index_end + 1
|
||||
};
|
||||
|
||||
let has_symbol_on_the_left =
|
||||
line.chars().nth(index_start).is_some_and(is_gear_symbol);
|
||||
if has_symbol_on_the_left {
|
||||
let mut number_position = number_position.to_owned();
|
||||
number_position.gear_position.index_line = index_line;
|
||||
number_position.gear_position.index_character = index_start;
|
||||
number_positions.push(number_position);
|
||||
}
|
||||
|
||||
let has_symbol_on_the_right =
|
||||
line.chars().nth(index_end).is_some_and(is_gear_symbol);
|
||||
if has_symbol_on_the_right {
|
||||
let mut number_position = number_position.to_owned();
|
||||
number_position.gear_position.index_line = index_line;
|
||||
number_position.gear_position.index_character = index_end;
|
||||
number_positions.push(number_position);
|
||||
}
|
||||
|
||||
let index_character_top =
|
||||
lines.get(index_line.saturating_sub(1)).and_then(|&line| {
|
||||
line.get(index_start..=index_end)
|
||||
.and_then(|value| value.chars().position(is_gear_symbol))
|
||||
});
|
||||
if let Some(index_character_top) = index_character_top {
|
||||
let mut number_position = number_position.to_owned();
|
||||
number_position.gear_position.index_line = index_line.saturating_sub(1);
|
||||
number_position.gear_position.index_character =
|
||||
index_character_top + index_start;
|
||||
number_positions.push(number_position);
|
||||
}
|
||||
|
||||
let index_character_bottom = lines.get(index_line + 1).and_then(|&line| {
|
||||
line.get(index_start..=index_end)
|
||||
.and_then(|value| value.chars().position(is_gear_symbol))
|
||||
});
|
||||
if let Some(index_character_bottom) = index_character_bottom {
|
||||
let mut number_position = number_position.to_owned();
|
||||
number_position.gear_position.index_line = index_line + 1;
|
||||
number_position.gear_position.index_character =
|
||||
index_character_bottom + index_start;
|
||||
number_positions.push(number_position);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Key: "index_line-index_character"
|
||||
// Value: usize
|
||||
let mut gear_positions: HashMap<String, Vec<usize>> = HashMap::new();
|
||||
|
||||
number_positions.iter().for_each(|&number_position| {
|
||||
let key = format!(
|
||||
"{}-{}",
|
||||
number_position.gear_position.index_line, number_position.gear_position.index_character,
|
||||
);
|
||||
match gear_positions.get_mut(&key) {
|
||||
Some(gear_positions) => {
|
||||
gear_positions.push(number_position.value);
|
||||
}
|
||||
None => {
|
||||
gear_positions.insert(key, vec![number_position.value]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let mut result = 0;
|
||||
|
||||
for (_, value) in gear_positions.iter() {
|
||||
if value.len() != 2 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let first_number = value.first();
|
||||
let second_number = value.last();
|
||||
|
||||
if let (Some(first_number), Some(second_number)) = (first_number, second_number) {
|
||||
result += first_number * second_number;
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod day_3_tests {
|
||||
@ -101,8 +209,8 @@ mod day_3_tests {
|
||||
assert_eq!(part_1(include_str!("../input_example_1.txt")), 4361);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_part_2_example() {
|
||||
// assert_eq!(part_2(include_str!("../input_example_1.txt")), 467835);
|
||||
// }
|
||||
#[test]
|
||||
fn test_part_2_example() {
|
||||
assert_eq!(part_2(include_str!("../input_example_1.txt")), 467835);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use day_3::part_1;
|
||||
use day_3::{part_1, part_2};
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("../input.txt");
|
||||
println!("- Day 3: Gear Ratios -");
|
||||
println!("Answer Part 1: {}", part_1(input));
|
||||
// println!("Answer Part 2: {}", part_2(input));
|
||||
println!("Answer Part 2: {}", part_2(input));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user