//! Day 1: Trebuchet?! use aho_corasick::AhoCorasick; pub const DAY: u8 = 1; pub const TITLE: &str = "Trebuchet?!"; pub fn part1(input: Vec) -> String { input .iter() .map(|line| { let numbers = line .chars() .filter(char::is_ascii_digit) .collect::>(); let (first, last) = (numbers.first().unwrap(), numbers.last().unwrap()); first.to_digit(10).unwrap() * 10 + last.to_digit(10).unwrap() }) .sum::() .to_string() } pub fn part2(input: Vec) -> 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::() .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"); } }