diff --git a/aoc_2025/src/day3.rs b/aoc_2025/src/day3.rs new file mode 100644 index 0000000..653199a --- /dev/null +++ b/aoc_2025/src/day3.rs @@ -0,0 +1,100 @@ +use std::iter::Sum; + +use crate::{AoC, Day, SimpleDay, WinnowDay}; +use winnow::{ + Parser, Result, + ascii::newline, + combinator::{repeat, terminated}, + error::ContextError, + token::one_of, +}; + +fn day() -> impl WinnowDay { + AoC::new(parse as _, part1 as _, part2 as _) +} + +fn parse<'a, 'b>(input: &'a mut &'b str) -> Result>> { + repeat(1.., parse_line).parse_next(input) +} + +fn parse_line(input: &mut &str) -> Result, ContextError> { + terminated( + repeat( + 1.., + one_of(('0'..='9',)).map(|c: char| c.to_string().parse::().unwrap()), + ), + newline, + ) + .parse_next(input) +} + +fn part1(input: Vec>) -> usize { + input.iter().map(joltage(2)).sum() +} + +fn part2(input: Vec>) -> usize { + input.iter().map(joltage(12)).sum() +} + +fn joltage< + 'a, + B: IntoIterator + Copy, + I: ExactSizeIterator, + N: Sum<&'a N> + Into + From + Copy + Default + 'a, +>( + size: usize, +) -> impl Fn(B) -> N { + move |line| { + (line.into_iter().len() - size..line.into_iter().len()) + .fold((0, 0), |(start, val), end| { + line.into_iter() + .enumerate() + .skip(start) + .take(end - start + 1) + .map(|(i, v)| (i + 1, (*v).into() + val * 10)) + .reduce(|a, b| if a.1 >= b.1 { a } else { b }) + .unwrap() + }) + .1 + .into() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn part1_test() { + day().assert1( + "987654321111111 +811111111111119 +234234234234278 +818181911112111 +", + "357", + ); + } + + #[test] + fn part1_solve() { + day().assert1(include_str!("../input/day3.txt"), "17343"); + } + + #[test] + fn part2_test() { + day().assert2( + "987654321111111 +811111111111119 +234234234234278 +818181911112111 +", + "3121910778619", + ); + } + + #[test] + fn part2_solve() { + day().assert2(include_str!("../input/day3.txt"), "172664333119298"); + } +} diff --git a/aoc_2025/src/lib.rs b/aoc_2025/src/lib.rs index 3e99aa9..435b796 100644 --- a/aoc_2025/src/lib.rs +++ b/aoc_2025/src/lib.rs @@ -7,6 +7,7 @@ use winnow::Parser; mod day1; mod day2; +mod day3; trait Day { fn assert1(&self, input: &str, output: &str);