#![forbid(elided_lifetimes_in_paths, unsafe_code)] use aoc23::read; use chumsky::prelude::*; use std::{io::{BufReader, BufRead}, fs::File}; use chumsky::chain::Chain; 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("twoone").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) // .map(|number| { eprintln!("{number}"); number }) .sum(); println!("{sum}"); let mut sum: u128 = 0; for line in BufReader::new(File::open("inputs/day1.txt")?).lines() { let line = line?; let line = line.trim(); if line.is_empty() { continue; } let mut digits = Vec::new(); for i in 0 .. line.len() { let s = &line[i..]; macro_rules! check_digit { ($digit:literal, $string:literal) => { if s.starts_with(stringify!($digit)) || line[i..].starts_with($string) { digits.push($digit); } } } check_digit!(1, "one"); check_digit!(2, "two"); check_digit!(3, "three"); check_digit!(4, "four"); check_digit!(5, "five"); check_digit!(6, "six"); check_digit!(7, "seven"); check_digit!(8, "eight"); check_digit!(9, "nine"); } sum += digits.first().unwrap() * 10 + digits.last().unwrap(); } println!("{sum}"); Ok(()) }