aoc day 3 part 1 done, annoying bug: you need to add a number if it's still counting up per line

This commit is contained in:
2023-12-04 14:49:33 +01:00
parent a671d0abaf
commit 1d6b0f2468
4 changed files with 331 additions and 0 deletions

View File

@@ -0,0 +1,172 @@
use std::fmt;
#[derive(Debug, Clone, Copy, Default)]
enum Tile {
#[default]
Empty,
Symbol(char),
Digit(u64),
}
impl fmt::Display for Tile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Tile::Empty => write!(f, "."),
Tile::Symbol(s) => write!(f, "{}", s),
Tile::Digit(d) => write!(f, "{}", d),
}
}
}
fn parse_input(input: &str) -> Vec<Vec<Tile>> {
let mut result = vec![];
for line in input.lines() {
let mut line_result = vec![];
for c in line.chars() {
if let Some(d) = c.to_digit(10) {
line_result.push(Tile::Digit(d as u64));
} else {
line_result.push(match c {
'.' => Tile::Empty,
s => Tile::Symbol(s),
})
}
}
result.push(line_result);
}
result
}
fn get_engine_part_positions(engine: &Vec<Vec<Tile>>) -> Vec<(u64, usize, (usize, usize))> {
let mut engine_parts = vec![];
for (row_number, row) in engine.iter().enumerate() {
let mut engine_part = 0;
let mut engine_part_start = 0;
let mut checking_engine_part = false;
for (column_number, tile) in row.iter().enumerate() {
match tile {
Tile::Digit(d) => {
if !checking_engine_part {
engine_part_start = column_number;
checking_engine_part = true;
}
engine_part = engine_part * 10 + d;
}
_ => {
if checking_engine_part {
checking_engine_part = false;
engine_parts.push((
engine_part,
row_number,
(engine_part_start, column_number - 1),
));
engine_part = 0;
}
}
}
}
if checking_engine_part {
engine_parts.push((engine_part, row_number, (engine_part_start, row.len() - 2)));
}
}
engine_parts
}
fn get_positions_to_check(
engine_part_position: (usize, (usize, usize)),
engine_width: usize,
engine_height: usize,
) -> Vec<(usize, usize)> {
let mut positions_to_check = vec![];
let (row, (column_start, column_end)) = engine_part_position;
if row > 0 {
for column in column_start..=column_end {
positions_to_check.push((row - 1, column));
}
if column_start > 0 {
positions_to_check.push((row - 1, column_start - 1));
}
if column_start < engine_width - 1 {
positions_to_check.push((row - 1, column_end + 1));
}
}
if row < engine_height - 1 {
for column in column_start..=column_end {
positions_to_check.push((row + 1, column));
}
if column_start > 0 {
positions_to_check.push((row + 1, column_start - 1));
}
if column_end < engine_width - 1 {
positions_to_check.push((row + 1, column_end + 1));
}
}
if column_start > 0 {
positions_to_check.push((row, column_start - 1));
}
if column_end < engine_width - 1 {
positions_to_check.push((row, column_end + 1));
}
positions_to_check
}
fn solve_1(engine: &Vec<Vec<Tile>>) -> u64 {
let mut result = 0;
let engine_width = engine[0].len();
let engine_height = engine.len();
let engine_part_positions = get_engine_part_positions(&engine);
for (part_number, row, (column_start, column_end)) in engine_part_positions {
let positions_to_check = get_positions_to_check(
(row, (column_start, column_end)),
engine_width,
engine_height,
);
if positions_to_check.iter().any(|&(x, y)| match engine[x][y] {
Tile::Symbol(_) => true,
_ => false,
}) {
result += part_number;
}
}
result
}
fn main() {
println!("Hello, this is Patrick!");
let input_txt = include_str!("../input.txt");
let engine = parse_input(input_txt);
println!(
"The sum of all the part numbers in the engine schematic is {}",
solve_1(&engine)
);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_1() {
let test_input = include_str!("../test_input.txt");
let engine = parse_input(test_input);
assert_eq!(solve_1(&engine), 4361);
}
}