Make functions public
Move valid number filtering to separate function for more granular testing
This commit is contained in:
parent
a9c3b9a3a0
commit
5fe3d1caa8
|
@ -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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue