diff --git a/advent_of_code/2023/3/src/main.rs b/advent_of_code/2023/3/src/main.rs index f8c3225..a394046 100644 --- a/advent_of_code/2023/3/src/main.rs +++ b/advent_of_code/2023/3/src/main.rs @@ -1,3 +1,4 @@ +use std::collections::HashSet; use std::fmt; #[derive(Debug, Clone, Copy, Default)] @@ -119,6 +120,41 @@ fn get_positions_to_check( positions_to_check } +fn get_gear_positions(engine: &Vec>) -> Vec<(usize, usize)> { + let mut result = vec![]; + for (row_number, row) in engine.iter().enumerate() { + for (column_number, tile) in row.iter().enumerate() { + match tile { + Tile::Symbol('*') => result.push((row_number, column_number)), + _ => {} + } + } + } + + result +} + +fn get_gear_ratio_number(engine: &Vec>, starting_point: (usize, usize)) -> u64 { + let mut starting_column = starting_point.1; + + while let Some(Tile::Digit(_)) = engine[starting_point.0].get(starting_column - 1) { + starting_column -= 1; + if starting_column == 0 { + break; + } + } + + let mut result = 0; + let mut column = starting_column; + + while let Some(Tile::Digit(d)) = engine[starting_point.0].get(column) { + result = result * 10 + d; + column += 1; + } + + result +} + fn solve_1(engine: &Vec>) -> u64 { let mut result = 0; let engine_width = engine[0].len(); @@ -144,6 +180,43 @@ fn solve_1(engine: &Vec>) -> u64 { result } +fn solve_2(engine: &Vec>) -> u64 { + let mut result = 0; + + let engine_width = engine[0].len(); + let engine_height = engine.len(); + + let gears_to_check = get_gear_positions(&engine); + + for (gear_x, gear_y) in gears_to_check { + let positions_to_check = + get_positions_to_check((gear_x, (gear_y, gear_y)), engine_width, engine_height); + + let mut adjacent_engine_part_positions = HashSet::new(); + for (x, y) in positions_to_check { + match engine[x][y] { + Tile::Digit(_) => { + if !(adjacent_engine_part_positions.contains(&(x, y - 1)) + || adjacent_engine_part_positions.contains(&(x, y + 1))) + { + adjacent_engine_part_positions.insert((x, y)); + } + } + _ => {} + } + } + + if adjacent_engine_part_positions.len() == 2 { + result += adjacent_engine_part_positions + .into_iter() + .map(|coord| get_gear_ratio_number(&engine, coord)) + .product::(); + } + } + + result +} + fn main() { println!("Hello, this is Patrick!"); @@ -155,6 +228,11 @@ fn main() { "The sum of all the part numbers in the engine schematic is {}", solve_1(&engine) ); + + println!( + "The sum of all gear ratios in the engine schematic is {}", + solve_2(&engine) + ); } #[cfg(test)] @@ -169,4 +247,13 @@ mod tests { assert_eq!(solve_1(&engine), 4361); } + + #[test] + fn test_2() { + let test_input = include_str!("../test_input.txt"); + + let engine = parse_input(test_input); + + assert_eq!(solve_2(&engine), 467835); + } }