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:
172
advent_of_code/2023/3/src/main.rs
Normal file
172
advent_of_code/2023/3/src/main.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user