1use crate::util::parse::*;
6
7const DIGITS: [&[u8]; 9] =
9 [b"one", b"two", b"three", b"four", b"five", b"six", b"seven", b"eight", b"nine"];
10
11pub fn parse(input: &str) -> Vec<&[u8]> {
12 input.lines().map(str::as_bytes).collect()
13}
14
15pub fn part1(input: &[&[u8]]) -> u32 {
16 input
17 .iter()
18 .map(|line| {
19 let first = line.iter().find(|b| b.is_ascii_digit()).unwrap().to_decimal();
20 let last = line.iter().rfind(|b| b.is_ascii_digit()).unwrap().to_decimal();
21 (10 * first + last) as u32
22 })
23 .sum()
24}
25
26pub fn part2(input: &[&[u8]]) -> u32 {
27 input
28 .iter()
29 .map(|line| {
30 let digit = |i: usize| -> Option<u32> {
31 if line[i].is_ascii_digit() {
32 return Some(line[i].to_decimal() as u32);
33 }
34 DIGITS
35 .iter()
36 .zip(1..)
37 .find_map(|(digit, value)| line[i..].starts_with(digit).then_some(value))
38 };
39
40 let first = (0..line.len()).find_map(digit).unwrap();
41 let last = (0..line.len()).rev().find_map(digit).unwrap();
42 10 * first + last
43 })
44 .sum()
45}