use anyhow::Context; use crate::{Problem, Solution}; pub struct Day01; impl Problem for Day01 { const DAY: u8 = 1; const INPUT: &'static str = include_str!("../input/day_01.txt"); } impl Solution for Day01 { type Answer1 = usize; type Answer2 = usize; fn part_1(input: &str) -> anyhow::Result { input.trim().split('\n').try_fold(0, |acc, line| { let first = line .chars() .find_map(|c| c.to_digit(10).map(|n| n as usize)) .context("Failed to find first number")?; let last = line .chars() .rev() .find_map(|c| c.to_digit(10).map(|n| n as usize)) .unwrap_or(first); Ok(acc + first * 10 + last) }) } fn part_2(input: &str) -> anyhow::Result { let words = [ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", ]; input.trim().split('\n').try_fold(0, |acc, line| { let mut buf = String::new(); let first = line .chars() .find_map(|c| { buf.push(c); words .iter() .enumerate() .find_map(|(n, w)| buf.contains(w).then_some(n)) .or_else(|| c.to_digit(10).map(|n| n as usize)) }) .context("Failed to find first number")?; buf.clear(); let last = line .chars() .rev() .find_map(|c| { buf.insert(0, c); words .iter() .enumerate() .find_map(|(n, w)| buf.contains(w).then_some(n)) .or_else(|| c.to_digit(10).map(|n| n as usize)) }) .unwrap_or(first); Ok(acc + first * 10 + last) }) } } #[cfg(test)] mod tests { use super::*; #[test] fn test_part_1() -> anyhow::Result<()> { let input = indoc::indoc! {" 1abc2 pqr3stu8vwx a1b2c3d4e5f treb7uchet "}; Ok(assert_eq!(142, Day01::part_1(input)?)) } #[test] fn test_part_2() -> anyhow::Result<()> { let input = indoc::indoc! {" two1nine eightwothree abcone2threexyz xtwone3four 4nineeightseven2 zoneight234 7pqrstsixteen "}; Ok(assert_eq!(281, Day01::part_2(input)?)) } }