day3 solution
parent
d2fdbae3ae
commit
428efcbfc1
|
@ -0,0 +1,133 @@
|
||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
type PartList = BTreeMap<(usize, usize, char), Vec<u32>>;
|
||||||
|
|
||||||
|
fn parse(input: &str) -> Vec<Vec<char>> {
|
||||||
|
input
|
||||||
|
.lines()
|
||||||
|
.filter_map(|line| {
|
||||||
|
if !line.is_empty() {
|
||||||
|
Some(line.chars().collect::<Vec<char>>())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc_generator(day3)]
|
||||||
|
fn associate_parts(input: &str) -> PartList {
|
||||||
|
let parsed_input = parse(input);
|
||||||
|
let mut result: PartList = BTreeMap::new();
|
||||||
|
for (line_index, line) in parsed_input.iter().enumerate() {
|
||||||
|
let mut parse_end = 0;
|
||||||
|
for (index, c) in line.iter().enumerate() {
|
||||||
|
if index < parse_end {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if c.is_ascii_digit() {
|
||||||
|
let mut n: Vec<char> = vec![];
|
||||||
|
n.push(*c);
|
||||||
|
if index + 1 < line.len() && line[index + 1].is_ascii_digit() {
|
||||||
|
n.push(line[index + 1]);
|
||||||
|
if index + 2 < line.len() && line[index + 2].is_ascii_digit() {
|
||||||
|
n.push(line[index + 2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let part_num = n
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("")
|
||||||
|
.parse::<u32>()
|
||||||
|
.unwrap();
|
||||||
|
let mut adjacent: Vec<(usize, usize)> = vec![];
|
||||||
|
let mut left_side = index;
|
||||||
|
if index > 1 {
|
||||||
|
left_side -= 1;
|
||||||
|
}
|
||||||
|
let mut right_side = index + n.len() - 1;
|
||||||
|
if right_side < line.len() - 1 {
|
||||||
|
right_side += 1;
|
||||||
|
}
|
||||||
|
parse_end = right_side;
|
||||||
|
let mut top_side = line_index;
|
||||||
|
if top_side > 1 {
|
||||||
|
top_side -= 1;
|
||||||
|
}
|
||||||
|
let mut bottom_side = line_index;
|
||||||
|
if bottom_side + 1 <= parsed_input.len() - 1 {
|
||||||
|
bottom_side += 1;
|
||||||
|
}
|
||||||
|
adjacent.push((line_index, left_side));
|
||||||
|
adjacent.push((line_index, right_side));
|
||||||
|
for col in left_side..=right_side {
|
||||||
|
adjacent.push((top_side, col));
|
||||||
|
adjacent.push((bottom_side, col));
|
||||||
|
}
|
||||||
|
if let Some(part_coord) = adjacent.iter().find(|coord| {
|
||||||
|
!parsed_input[coord.0][coord.1].is_ascii_digit()
|
||||||
|
&& parsed_input[coord.0][coord.1] != '.'
|
||||||
|
}) {
|
||||||
|
let hash_key = (
|
||||||
|
part_coord.0,
|
||||||
|
part_coord.1,
|
||||||
|
parsed_input[part_coord.0][part_coord.1],
|
||||||
|
);
|
||||||
|
if !result.contains_key(&hash_key) {
|
||||||
|
result.insert(hash_key, vec![]);
|
||||||
|
}
|
||||||
|
let plist = result.get_mut(&hash_key).unwrap();
|
||||||
|
plist.push(part_num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// println!("{:?}", result);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day3, part1)]
|
||||||
|
fn part1(input: &PartList) -> u32 {
|
||||||
|
let mut sum: u32 = 0;
|
||||||
|
for (_coord, plist) in input.iter() {
|
||||||
|
sum += plist.iter().sum::<u32>();
|
||||||
|
}
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day3, part2)]
|
||||||
|
fn part2(input: &PartList) -> u32 {
|
||||||
|
let mut sum: u32 = 0;
|
||||||
|
for (coord, plist) in input.iter() {
|
||||||
|
if coord.2 == '*' && plist.len() == 2 {
|
||||||
|
sum += plist.iter().product::<u32>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const SAMPLE_DATA: &'static str = r#"467..114..
|
||||||
|
...*......
|
||||||
|
..35..633.
|
||||||
|
......#...
|
||||||
|
617*......
|
||||||
|
.....+.58.
|
||||||
|
..592.....
|
||||||
|
......755.
|
||||||
|
...$.*....
|
||||||
|
.664.598..
|
||||||
|
"#;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_data() {
|
||||||
|
let parts = associate_parts(&SAMPLE_DATA);
|
||||||
|
assert_eq!(part1(&parts), 4361);
|
||||||
|
assert_eq!(part2(&parts), 467835);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,5 +2,6 @@ use aoc_runner_derive::aoc_lib;
|
||||||
|
|
||||||
mod day01;
|
mod day01;
|
||||||
mod day02;
|
mod day02;
|
||||||
|
mod day03;
|
||||||
|
|
||||||
aoc_lib! { year = 2023 }
|
aoc_lib! { year = 2023 }
|
||||||
|
|
Loading…
Reference in New Issue