Make functions public

Move valid number filtering to separate function for more granular testing
This commit is contained in:
Evie Litherland-Smith 2024-01-06 07:19:13 +00:00
parent a9c3b9a3a0
commit 5fe3d1caa8

View file

@ -2,7 +2,7 @@ use regex::{Match, Regex};
use std::{fmt::Display, num::ParseIntError};
#[derive(Debug)]
struct Symbol {
pub struct Symbol {
value: char,
row: usize,
col: usize,
@ -15,7 +15,7 @@ impl Display for Symbol {
}
#[derive(Debug)]
struct Number {
pub struct Number {
value: u32,
row: usize,
start: usize,
@ -36,7 +36,7 @@ impl Display for Number {
}
impl Number {
fn valid(&self, symbols: &[Symbol]) -> bool {
pub fn is_valid(&self, symbols: &[Symbol]) -> bool {
let adjacent: Vec<usize> = symbols
.iter()
.filter_map(|m| {
@ -68,7 +68,7 @@ impl TryFrom<Match<'_>> for Number {
}
}
fn get_symbols(input: &str) -> Vec<Symbol> {
pub fn get_symbols(input: &str) -> Vec<Symbol> {
let mut items: Vec<Symbol> = Vec::new();
for (row, line) in input.lines().enumerate() {
for (col, value) in line.chars().enumerate() {
@ -80,40 +80,38 @@ fn get_symbols(input: &str) -> Vec<Symbol> {
items
}
fn get_numbers(input: &str) -> Vec<Number> {
pub fn get_numbers(input: &str, predicate: Option<&dyn Fn(&Number) -> bool>) -> 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);
if predicate.unwrap_or(&|_| true)(&number) {
items.push(number);
};
}
}
items
}
pub fn get_valid_numbers(input: &str, symbols: &[Symbol]) -> Vec<u32> {
get_numbers(input, Some(&|number| number.is_valid(symbols)))
.iter()
.map(|m| m.value)
.collect()
}
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 {
None
}
})
.sum()
get_valid_numbers(input, &symbols).iter().sum()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn example() {
let input = "467..114..
const INPUT: &str = "467..114..
...*......
..35..633.
......#...
@ -123,6 +121,9 @@ mod tests {
......755.
...$.*....
.664.598..";
assert_eq!(main(input), 4361);
#[test]
fn example() {
assert_eq!(main(INPUT), 4361);
}
}