solve year 2023 day 03

This commit is contained in:
2023-12-04 00:25:09 +01:00
parent bae3757f13
commit a53a8412dc
5 changed files with 250 additions and 1 deletions

View File

@@ -22,4 +22,5 @@ pub mod year2022 {
pub mod year2023 {
pub mod day01;
pub mod day02;
pub mod day03;
}

View File

@@ -94,5 +94,9 @@ fn year2022() -> Vec<Solution> {
}
fn year2023() -> Vec<Solution> {
vec![solution!(year2023, day01), solution!(year2023, day02)]
vec![
solution!(year2023, day01),
solution!(year2023, day02),
solution!(year2023, day03),
]
}

View File

@@ -63,6 +63,19 @@ impl Ix2 {
pub fn linearize(&self, width: usize, height: usize) -> usize {
self.y() as usize * height + (width - 1)
}
pub fn neighbors(&self) -> [Self; 8] {
[
Dim([self.x() - 1, self.y() - 1]),
Dim([self.x(), self.y() - 1]),
Dim([self.x() + 1, self.y() - 1]),
Dim([self.x() - 1, self.y()]),
Dim([self.x() + 1, self.y()]),
Dim([self.x() - 1, self.y() + 1]),
Dim([self.x(), self.y() + 1]),
Dim([self.x() + 1, self.y() + 1]),
]
}
}
impl From<u8> for Ix2 {

91
src/year2023/day03.rs Normal file
View File

@@ -0,0 +1,91 @@
use std::collections::BTreeMap;
use crate::util::index::{Dim, Ix2};
fn parse_nums(input: &str) -> BTreeMap<Dim<[i64; 2]>, u32> {
let mut nums = BTreeMap::new();
for (lnr, line) in input.lines().enumerate() {
let mut line = line.chars().enumerate();
while let Some((x, c)) = line.next() {
if c.is_ascii_digit() {
let mut num = (c as u8 - b'0') as u32;
let mut end = x;
while let Some((idx, c)) = line.next() {
if c.is_ascii_digit() {
num = num * 10 + (c as u8 - b'0') as u32;
end = idx;
} else {
break;
}
}
for x2 in x..=end {
nums.insert(Dim([x2 as i64, lnr as i64]), num);
}
}
}
}
nums
}
pub fn part1(input: &str) -> impl std::fmt::Display {
let nums = parse_nums(input);
input
.lines()
.enumerate()
.flat_map(|(lnr, line)| {
line.chars()
.enumerate()
.filter(|(_, c)| *c != '.' && !c.is_ascii_digit())
.map(|(cnr, _)| {
let coord = Ix2::from([cnr as i64, lnr as i64]);
let mut vals = coord
.neighbors()
.iter()
.filter_map(|idx| nums.get(idx))
.collect::<Vec<_>>();
vals.dedup();
vals.into_iter().sum::<u32>()
})
.collect::<Vec<_>>()
})
.sum::<u32>()
}
pub fn part2(input: &str) -> impl std::fmt::Display {
let nums = parse_nums(input);
input
.lines()
.enumerate()
.flat_map(|(lnr, line)| {
line.chars()
.enumerate()
.filter(|(_, c)| *c == '*')
.filter_map(|(cnr, _)| {
let coord = Ix2::from([cnr as i64, lnr as i64]);
let mut vals = coord
.neighbors()
.iter()
.filter_map(|idx| nums.get(idx))
.collect::<Vec<_>>();
vals.dedup();
if vals.len() == 2 {
return Some(vals.into_iter().product::<u32>());
};
None
})
.collect::<Vec<_>>()
})
.sum::<u32>()
}
#[test]
fn test_part1() {
assert_eq!("", part1("").to_string())
}
#[test]
fn test_part2() {
assert_eq!("", part2("").to_string())
}