mirror of
https://github.com/theoludwig/advent_of_code_2023.git
synced 2024-10-29 22:17:19 +01:00
feat: add day 3 - part 2
This commit is contained in:
parent
96a0eb6d4d
commit
cee59608de
@ -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?**
|
**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: `**`.**
|
**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 struct NumberPosition {
|
||||||
pub index_start: usize,
|
pub index_start: usize,
|
||||||
pub index_end: usize,
|
pub index_end: usize,
|
||||||
pub value: usize,
|
pub value: usize,
|
||||||
|
pub gear_position: GearPosition,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_numbers_positions_from_line(line: &str) -> Vec<NumberPosition> {
|
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_start,
|
||||||
index_end,
|
index_end,
|
||||||
value,
|
value,
|
||||||
|
gear_position: GearPosition::default(),
|
||||||
});
|
});
|
||||||
number_string = String::from("");
|
number_string = String::from("");
|
||||||
index_start = 0;
|
index_start = 0;
|
||||||
@ -35,6 +45,7 @@ pub fn get_numbers_positions_from_line(line: &str) -> Vec<NumberPosition> {
|
|||||||
index_start,
|
index_start,
|
||||||
index_end,
|
index_end,
|
||||||
value,
|
value,
|
||||||
|
gear_position: GearPosition::default(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
@ -44,6 +55,10 @@ pub fn is_symbol(character: char) -> bool {
|
|||||||
!character.is_ascii_digit() && character != '.'
|
!character.is_ascii_digit() && character != '.'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_gear_symbol(character: char) -> bool {
|
||||||
|
character == '*'
|
||||||
|
}
|
||||||
|
|
||||||
pub fn part_1(input: &str) -> usize {
|
pub fn part_1(input: &str) -> usize {
|
||||||
let lines = input.lines().collect::<Vec<&str>>();
|
let lines = input.lines().collect::<Vec<&str>>();
|
||||||
lines
|
lines
|
||||||
@ -82,15 +97,108 @@ pub fn part_1(input: &str) -> usize {
|
|||||||
|| has_symbol_on_the_top
|
|| has_symbol_on_the_top
|
||||||
|| has_symbol_on_the_bottom
|
|| has_symbol_on_the_bottom
|
||||||
})
|
})
|
||||||
.map(|matching_number| matching_number.value)
|
.map(|number_position| number_position.value)
|
||||||
.sum::<usize>()
|
.sum::<usize>()
|
||||||
})
|
})
|
||||||
.sum()
|
.sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn part_2(_input: &str) -> usize {
|
pub fn part_2(input: &str) -> usize {
|
||||||
// 42
|
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)]
|
#[cfg(test)]
|
||||||
mod day_3_tests {
|
mod day_3_tests {
|
||||||
@ -101,8 +209,8 @@ mod day_3_tests {
|
|||||||
assert_eq!(part_1(include_str!("../input_example_1.txt")), 4361);
|
assert_eq!(part_1(include_str!("../input_example_1.txt")), 4361);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn test_part_2_example() {
|
fn test_part_2_example() {
|
||||||
// assert_eq!(part_2(include_str!("../input_example_1.txt")), 467835);
|
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() {
|
fn main() {
|
||||||
let input = include_str!("../input.txt");
|
let input = include_str!("../input.txt");
|
||||||
println!("- Day 3: Gear Ratios -");
|
println!("- Day 3: Gear Ratios -");
|
||||||
println!("Answer Part 1: {}", part_1(input));
|
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