adventofcode23/src/day1.rs

72 lines
1.7 KiB
Rust

//! Day 1: Trebuchet?!
use aho_corasick::AhoCorasick;
pub const DAY: u8 = 1;
pub const TITLE: &str = "Trebuchet?!";
pub fn part1(input: Vec<String>) -> String {
input
.iter()
.map(|line| {
let numbers = line
.chars()
.filter(char::is_ascii_digit)
.collect::<Vec<_>>();
let (first, last) = (numbers.first().unwrap(), numbers.last().unwrap());
first.to_digit(10).unwrap() * 10 + last.to_digit(10).unwrap()
})
.sum::<u32>()
.to_string()
}
pub fn part2(input: Vec<String>) -> String {
let ac = AhoCorasick::new([
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine",
])
.unwrap();
input
.iter()
.map(|line| {
let mut numbers = ac.find_overlapping_iter(line).map(|m| {
let p = m.pattern().as_u32();
if p < 10 {
p
} else {
p - 9
}
});
let first = numbers.next().expect(line);
let last = numbers.last().unwrap_or(first);
first * 10 + last
})
.sum::<u32>()
.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn t_example1() {
assert_eq!(part1(crate::read_example(DAY, 1)), "142");
}
#[test]
fn t_part1() {
assert_eq!(part1(crate::read_input(DAY)), "56049");
}
#[test]
fn t_example2() {
assert_eq!(part2(crate::read_example(DAY, 2)), "281");
}
#[test]
fn t_part2() {
assert_eq!(part2(crate::read_input(DAY)), "54530");
}
}