Day3 part1 solution with passing tests (but failing solution)

This commit is contained in:
Evie Litherland-Smith 2023-12-29 15:50:35 +00:00
parent 9acc2bbb93
commit 2c88cb8fe8

View file

@ -1,55 +1,110 @@
use regex::Regex; use regex::{Match, Regex};
use std::{fmt::Display, num::ParseIntError};
pub fn main(input: &str) -> i32 { #[derive(Debug)]
todo!(); struct Symbol {
value: char,
row: usize,
col: usize,
}
impl Display for Symbol {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: ({},{})", self.value, self.row + 1, self.col + 1)
}
} }
#[derive(Debug)] #[derive(Debug)]
enum Engine { struct Number {
Number { value: u32,
value: u32, row: usize,
line: usize, start: usize,
start: usize, end: usize,
end: usize,
},
Symbol {
value: char,
line: usize,
pos: usize,
},
} }
fn get_numbers(index: usize, line: &str) -> Vec<Engine> { impl Display for Number {
Regex::new(r"\d+") fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
.unwrap() write!(
.find_iter(line) f,
.filter_map(|m| match m.as_str().parse() { "{0}: ({1},{2}) -> ({1},{3})",
Ok(value) => Some(Engine::Number { self.value,
value, self.row + 1,
line: index, self.start + 1,
start: m.start(), self.end + 1,
end: m.end(), )
}), }
_ => None, }
impl Number {
fn valid(&self, symbols: &[Symbol]) -> bool {
let adjacent: Vec<usize> = symbols
.iter()
.filter_map(|m| {
let start = if self.row > 1 { self.row - 1 } else { 1 };
let end = self.row + 1;
if (start..=end).contains(&m.row) {
Some(m.col)
} else {
None
}
})
.collect();
let start = if self.start > 1 { self.start - 1 } else { 1 };
let end = self.end + 1;
(start..=end).any(|m| adjacent.contains(&m))
}
}
impl TryFrom<Match<'_>> for Number {
type Error = ParseIntError;
fn try_from(value: Match) -> Result<Self, Self::Error> {
Ok(Self {
value: value.as_str().parse()?,
row: 0,
start: value.start(),
end: value.end(),
}) })
.collect() }
} }
fn get_symbols(index: usize, line: &str) -> Vec<Engine> { fn get_symbols(input: &str) -> Vec<Symbol> {
line.chars() let mut items: Vec<Symbol> = Vec::new();
.enumerate() for (row, line) in input.lines().enumerate() {
.filter_map(|(j, m)| { for (col, value) in line.chars().enumerate() {
if !m.is_ascii_digit() && m != '.' { if !value.is_ascii_digit() && value != '.' {
Some(Engine::Symbol { items.push(Symbol { value, row, col })
value: m, }
line: index, }
pos: j, }
}) items
}
fn get_numbers(input: &str) -> Vec<Number> {
let rstring = r"(\d)+";
let mut items: Vec<Number> = Vec::new();
for (row, line) in input.lines().enumerate() {
for item in Regex::new(rstring).unwrap().find_iter(line) {
let mut number = Number::try_from(item).unwrap();
number.row = row;
items.push(number);
}
}
items
}
pub fn main(input: &str) -> u32 {
let symbols = get_symbols(input);
get_numbers(input)
.iter()
.filter_map(|m| {
if m.valid(&symbols) {
Some(m.value)
} else { } else {
None None
} }
}) })
.collect() .sum()
} }
#[cfg(test)] #[cfg(test)]