advent-of-code/2023/rust/src/day3.rs

124 lines
3.5 KiB
Rust

mod prelude;
use std::{collections::HashSet, iter::FromIterator};
use crate::prelude::*;
fn main() {
Day3::show(day_input(3), day_input(3))
}
struct Day3 {}
impl Day3 {
fn adjacent_nums(chargrid: &Vec<Vec<char>>, y: usize, x: usize) -> Vec<usize> {
let mut result = vec![];
let h = chargrid.len();
let w = chargrid[0].len();
let miny = (y - 1).clamp(0, h);
let minx = (x - 1).clamp(0, w);
let maxy = (y + 1).clamp(0, h);
let maxx = (x + 1).clamp(0, w);
let mut scanned: HashSet<(usize, usize)> = HashSet::new();
println!("symbol at {y} {x}: {}", chargrid[y][x]);
for y in miny..=maxy {
for x in minx..=maxx {
if scanned.contains(&(y, x)) {
continue;
}
if chargrid[y][x].is_digit(10) {
println!("{y} {x} {}", chargrid[y][x]);
scanned.insert((y, x));
let mut rx = x;
let mut lx = x;
for rrx in (x + 1)..w {
if !chargrid[y][rrx].is_digit(10) {
break;
}
rx = rrx;
scanned.insert((y, rx));
}
for llx in (0..=(x - 1)).rev() {
if !chargrid[y][llx].is_digit(10) {
break;
}
lx = llx;
scanned.insert((y, lx));
}
let ns = String::from_iter(&chargrid[y][lx..=rx]);
println!("ns: {}", ns);
if let Ok(n) = ns.parse() {
result.push(n);
println!("FOUND: {n}");
}
}
}
}
result
}
}
impl AoCSolution for Day3 {
type Input = String;
type Solution = usize;
fn part1(input: Self::Input) -> Self::Solution {
let mut result = 0;
let chargrid: Vec<Vec<char>> = input.lines().map(|s| s.chars().collect()).collect();
println!("{chargrid:?}");
for y in 0..chargrid.len() {
let line = &chargrid[y];
for x in 0..line.len() {
let c = line[x];
if !c.is_digit(10) && c != '.' {
result += Self::adjacent_nums(&chargrid, y, x).iter().sum::<usize>();
}
}
}
result
}
fn part2(input: Self::Input) -> Self::Solution {
let mut result = 0;
let chargrid: Vec<Vec<char>> = input.lines().map(|s| s.chars().collect()).collect();
println!("{chargrid:?}");
for y in 0..chargrid.len() {
let line = &chargrid[y];
for x in 0..line.len() {
let c = line[x];
if c == '*' {
let nums = Self::adjacent_nums(&chargrid, y, x);
println!("nums: {nums:?}");
if nums.len() == 2 {
result += nums[0] * nums[1];
}
}
}
}
result
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let input = r#"467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598.."#;
println!("input:\n{input}");
assert_eq!(Day3::part1(input.into()), 4361);
assert_eq!(Day3::part2(input.into()), 467835);
}
}