diff --git a/Day03/README.md b/Day03/README.md index 608f47d..edfe1ee 100644 --- a/Day03/README.md +++ b/Day03/README.md @@ -58,3 +58,10 @@ Consider the same engine schematic again: In this schematic, there are two gears. The first is in the top left; it has part numbers 467 and 35, so its gear ratio is 16345. The second gear is in the lower right; its gear ratio is 451490. (The * adjacent to 617 is not a gear because it is only adjacent to one part number.) Adding up all of the gear ratios produces 467835. What is the sum of all of the gear ratios in your engine schematic? + + +## Solution Algorithm +1. **Read the Schematic**: Read the engine schematic from a file into a grid format for processing. +2. **Identify Part Numbers**: For each character in the grid, check if it's adjacent to a symbol (other than .). If so, extract the full number starting from that digit (ensuring left-to-right reading). +3. **Find Gears and Calculate Ratios**: Iterate through the grid and identify * symbols. For each *, find all adjacent part numbers. If exactly two part numbers are found, calculate the gear ratio by multiplying these two numbers. +3. **Sum Gear Ratios**: Add up all the calculated gear ratios to get the total sum. diff --git a/Day03/rust/Cargo.toml b/Day03/rust/Cargo.toml new file mode 100644 index 0000000..1ec6963 --- /dev/null +++ b/Day03/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/Day03/rust/src/main.rs b/Day03/rust/src/main.rs new file mode 100644 index 0000000..6e8df12 --- /dev/null +++ b/Day03/rust/src/main.rs @@ -0,0 +1,94 @@ +use std::fs::File; +use std::io::{self, BufRead, BufReader}; +use std::path::Path; + +fn parse_schematic(file_path: &Path) -> io::Result> { + let file = File::open(file_path)?; + let reader = BufReader::new(file); + reader.lines().collect() +} + +fn get_adjacent_positions(rows: usize, cols: usize, row: usize, col: usize) -> Vec<(usize, usize)> { + let mut positions = Vec::new(); + for i in row.saturating_sub(1)..=(row + 1).min(rows - 1) { + for j in col.saturating_sub(1)..=(col + 1).min(cols - 1) { + if i != row || j != col { + positions.push((i, j)); + } + } + } + positions +} + +fn find_start_of_number(schematic: &[String], row: usize, mut col: usize) -> usize { + while col > 0 && schematic[row].chars().nth(col - 1).unwrap().is_digit(10) { + col -= 1; + } + col +} + +fn extract_full_number(schematic: &mut [String], start_row: usize, start_col: usize) -> i32 { + let start_col = find_start_of_number(schematic, start_row, start_col); + let mut number = String::new(); + let mut col = start_col; + + while col < schematic[start_row].len() && schematic[start_row].chars().nth(col).unwrap().is_digit(10) { + number.push(schematic[start_row].chars().nth(col).unwrap()); + schematic[start_row].replace_range(col..=col, "."); + col += 1; + } + + number.parse::().unwrap_or(0) +} + +fn find_gears_and_calculate_ratios(schematic: &mut Vec) -> i32 { + let rows = schematic.len(); + let cols = schematic[0].len(); + let mut total_ratio_sum = 0; + + for row in 0..rows { + for col in 0..cols { + if schematic[row].chars().nth(col).unwrap() == '*' { + let mut part_numbers = Vec::new(); + for (i, j) in get_adjacent_positions(rows, cols, row, col) { + if schematic[i].chars().nth(j).unwrap().is_digit(10) { + let part_number = extract_full_number(schematic, i, j); + if !part_numbers.contains(&part_number) { + part_numbers.push(part_number); + } + } + } + + if part_numbers.len() == 2 { + let gear_ratio = part_numbers[0] * part_numbers[1]; + total_ratio_sum += gear_ratio; + println!("Found gear at line {} with ratio {}", row + 1, gear_ratio); + } + } + } + } + + total_ratio_sum +} + +fn main() { + let test_path = Path::new("../test.txt"); + let input_path = Path::new("../input.txt"); + + match parse_schematic(test_path) { + Ok(mut test_schematic) => { + let test_result = find_gears_and_calculate_ratios(&mut test_schematic); + println!("Test Result: {}", test_result); + assert_eq!(test_result, 467835, "Test failed: Expected 467835"); + } + Err(e) => println!("Error reading test file: {}", e), + } + + match parse_schematic(input_path) { + Ok(mut input_schematic) => { + let total_ratio_sum = find_gears_and_calculate_ratios(&mut input_schematic); + println!("Total sum of gear ratios: {}", total_ratio_sum); + } + Err(e) => println!("Error reading input file: {}", e), + } +} diff --git a/README.md b/README.md index f1827b1..e309e62 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ I aim to complete each day's puzzle on the same day, but as with any challenge, |-----|----------|----------|-------------| | 01 | ✅ | ✅ | [Day01 README](/Day01/README.md) | | 02 | ✅ | ✅ | [Day02 README](/Day02/README.md) | -| 03 | ❓ | ❓ | [Day25 README](/Day03/README.md) | +| 03 | ✅ | ✅ | [Day25 README](/Day03/README.md) | | 04 | ❓ | ❓ | [Day25 README](/Day04/README.md) | | 05 | ❓ | ❓ | [Day25 README](/Day05/README.md) | | 06 | ❓ | ❓ | [Day25 README](/Day06/README.md) |