This commit is contained in:
Tyler Hallada 2023-12-03 02:22:36 -05:00
parent fea946a7df
commit a5969ced97
4 changed files with 166 additions and 0 deletions

10
src/day03/input/test1.txt Normal file
View File

@ -0,0 +1,10 @@
467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..

View File

@ -0,0 +1,5 @@
...123
*.....
.....&
.....4
...523

148
src/day03/mod.rs Normal file
View File

@ -0,0 +1,148 @@
use std::str::FromStr;
use anyhow::Result;
use crate::instrument::instrument;
const INPUT: &str = include_str!("input/input.txt");
#[derive(Debug, Copy, Clone)]
struct Coord {
x: usize,
y: usize,
}
#[derive(Debug)]
struct Number {
start: Coord,
end: Coord,
value: u32,
}
impl Number {
fn adjacent_to(&self, other: &Coord) -> bool {
other.x >= self.start.x.saturating_sub(1)
&& other.x <= self.end.x + 1
&& other.y >= self.start.y.saturating_sub(1)
&& other.y <= self.end.y + 1
}
}
#[derive(Debug)]
struct Engine {
symbols: Vec<Coord>,
numbers: Vec<Number>,
}
impl FromStr for Engine {
type Err = anyhow::Error;
#[allow(unused_assignments)]
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut symbols: Vec<Coord> = Vec::new();
let mut numbers: Vec<Number> = Vec::new();
for (y, line) in s.trim().split('\n').enumerate() {
let mut number_start: Option<Coord> = None;
let mut number_value = String::new();
for (x, char) in line.chars().enumerate() {
if char.is_ascii_digit() {
if number_start.is_none() {
number_start = Some(Coord { x, y });
}
number_value.push(char);
} else {
if char != '.' {
symbols.push(Coord { x, y });
}
if let Some(start) = number_start {
numbers.push(Number {
start,
end: Coord {
x: x.saturating_sub(1),
y,
},
value: number_value.parse()?,
});
}
number_start = None;
number_value = String::new();
}
}
if let Some(start) = number_start {
numbers.push(Number {
start,
end: Coord {
x: line.len() - 1,
y,
},
value: number_value.parse()?,
});
}
number_start = None;
number_value = String::new();
}
Ok(Self { symbols, numbers })
}
}
fn part1(input: &str) -> Result<u32> {
let engine = input.parse::<Engine>()?;
Ok(engine
.numbers
.into_iter()
.filter(|n| engine.symbols.iter().any(|s| n.adjacent_to(s)))
.map(|n| n.value)
.sum())
}
fn part2(input: &str) -> Result<u32> {
let engine = input.parse::<Engine>()?;
Ok(engine
.symbols
.into_iter()
.filter_map(|s| {
let adjacent_numbers = engine
.numbers
.iter()
.filter(|n| n.adjacent_to(&s))
.map(|n| n.value)
.collect::<Vec<u32>>();
if adjacent_numbers.len() == 2 {
return Some(adjacent_numbers[0] * adjacent_numbers[1]);
}
None
})
.sum())
}
pub fn solve() -> Result<()> {
println!("\nDay 03");
instrument!(part1(INPUT)?, part2(INPUT)?);
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT1: &str = include_str!("input/test1.txt");
#[test]
fn test_adjacent_to() {
assert!(Number {
start: Coord { x: 5, y: 9 },
end: Coord { x: 8, y: 9 },
value: 598
}
.adjacent_to(&Coord { x: 4, y: 8 }),);
}
#[test]
fn test_part1() {
assert_eq!(part1(TEST_INPUT1).unwrap(), 4361);
}
#[test]
fn test_part2() {
assert_eq!(part2(TEST_INPUT1).unwrap(), 467835);
}
}

View File

@ -1,5 +1,6 @@
pub mod day01; pub mod day01;
pub mod day02; pub mod day02;
pub mod day03;
pub mod instrument; pub mod instrument;
use anyhow::Result; use anyhow::Result;
@ -8,5 +9,7 @@ fn main() -> Result<()> {
println!("Advent of Code 2023"); println!("Advent of Code 2023");
day01::solve()?; day01::solve()?;
day02::solve()?; day02::solve()?;
day03::solve()?;
Ok(()) Ok(())
} }