#![forbid(elided_lifetimes_in_paths, unsafe_code)] use aoc23::read; use chumsky::prelude::*; struct Line { first_digit: u128, last_digit: u128 } // thanks rust fn array(array: &'static [T; N]) -> &'static [T] { array } impl Line { fn parser() -> impl Parser> { choice(( // digit combinations (only the relevant ones) just("oneight").map(|_| array(&[1, 8])), just("twone").map(|_| array(&[2, 1])), just("eightwo").map(|_| array(&[8, 2])), // single digits just("one").or(just("1")).map(|_| array(&[1])), just("two").or(just("2")).map(|_| array(&[2])), just("three").or(just("3")).map(|_| array(&[3])), just("four").or(just("4")).map(|_| array(&[4])), just("five").or(just("5")).map(|_| array(&[5])), just("six").or(just("6")).map(|_| array(&[6])), just("seven").or(just("7")).map(|_| array(&[7])), just("eight").or(just("8")).map(|_| array(&[8])), just("nine").or(just("9")).map(|_| array(&[9])), // garbage none_of(['1', '2', '3', '4', '5', '6', '7', '8', '9', '\n']) .map(|_| array(&[])) )) .repeated() .then_ignore(just('\n')) .map(|digits: Vec<&'static [u128]>| { let mut digits = digits.into_iter().flat_map(|array| array.iter().copied()); let first_digit = digits.next().expect("No digit in line"); let last_digit = digits.last().unwrap_or(first_digit); Line { first_digit, last_digit } }) } } fn parser() -> impl Parser, Error = Simple> { Line::parser().repeated().then_ignore(end()) } fn main() -> anyhow::Result<()> { let lines = read("inputs/day1.txt", parser())?; let sum: u128 = lines .iter() .map(|line| line.first_digit * 10 + line.last_digit) .sum(); println!("{sum}"); Ok(()) }