making 2023 a generic aoc repo

This commit is contained in:
Dylan Thies
2023-12-04 19:40:31 -05:00
parent 09f1da1295
commit 51cf3fa8e7
28 changed files with 2 additions and 2 deletions

113
2023/day-3/src/part2.rs Normal file
View File

@@ -0,0 +1,113 @@
#![warn(clippy::all, clippy::pedantic)]
use std::collections::BTreeMap;
#[derive(Debug)]
struct SerialNumber {
pub no: u64,
pub start: (usize, usize),
pub end: (usize, usize),
}
impl SerialNumber {
fn is_adjacent(&self, pos: (usize, usize)) -> bool {
usize::abs_diff(self.start.1, pos.1) < 2
&& self.start.0 < 2 + pos.0
&& pos.0 < 2 + self.end.0
}
}
#[must_use]
pub fn part2(input: &str) -> String {
let (serials, symbols) = parse_input(input);
symbols
.iter()
.filter_map(|(key, value)| if *value == '*' { Some(*key) } else { None })
.filter_map(|pos| {
let serials = serials
.iter()
.filter_map(|serial| {
if serial.is_adjacent(pos) {
Some(serial.no)
} else {
None
}
})
.collect::<Vec<u64>>();
if serials.len() == 2 {
Some(serials[0] * serials[1])
} else {
None
}
})
.sum::<u64>()
.to_string()
//find all serials next to '*' and map with '*' location
}
fn parse_input(input: &str) -> (Vec<SerialNumber>, BTreeMap<(usize, usize), char>) {
let mut numbers = Vec::new();
let mut symbols = BTreeMap::new();
for (line_no, line) in input.lines().enumerate() {
let mut prev_char = None;
let mut cur_no = 0_u64;
let mut cur_no_row_start = 0_usize;
for (row_no, c) in line.chars().enumerate() {
if let Some(d) = c.to_digit(10) {
if prev_char.is_some() {
cur_no = cur_no * 10 + u64::from(d);
} else {
cur_no = u64::from(d);
cur_no_row_start = row_no;
}
prev_char = Some(c);
} else {
if prev_char.is_some() {
//handle saving number off
numbers.push(SerialNumber {
no: cur_no,
start: (cur_no_row_start, line_no),
end: (row_no - 1, line_no),
});
}
prev_char = None;
if c == '.' {
//move along space
continue;
}
//store symbol
let _ = symbols.insert((row_no, line_no), c);
}
}
//need to account for new line numbers
if prev_char.is_some() {
numbers.push(SerialNumber {
no: cur_no,
start: (cur_no_row_start, line_no),
end: (line.len() - 1, line_no),
});
}
}
(numbers, symbols)
}
#[cfg(test)]
mod test {
use super::*;
const INPUT: &str = "467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..";
#[test]
fn part2_works() {
let result = part2(INPUT);
assert_eq!(result, "467835".to_string());
}
}