Advent of Code solutions in Rust

feat: day 3 of AoC 2025

+88 -2
+86
aoc_2025/src/day03.rs
··· 1 + use anyhow::Context as _; 2 + use aoc_companion::prelude::*; 3 + use itertools::Itertools as _; 4 + 5 + pub(crate) struct Door { 6 + banks: Vec<Vec<u32>>, 7 + } 8 + 9 + impl<'input> Solution<'input> for Door { 10 + fn parse(input: &'input str) -> Result<Self> { 11 + Ok(Door { 12 + banks: input 13 + .lines() 14 + .map(|line| { 15 + line.chars() 16 + .map(|c| { 17 + c.to_digit(10) 18 + .with_context(|| anyhow::anyhow!("{c:?} is not a digit")) 19 + }) 20 + .try_collect() 21 + }) 22 + .try_collect()?, 23 + }) 24 + } 25 + 26 + fn part1(&self) -> u64 { 27 + self.banks.iter().map(|b| max_joltage(b, 2)).sum() 28 + } 29 + 30 + fn part2(&self) -> u64 { 31 + self.banks.iter().map(|b| max_joltage(b, 12)).sum() 32 + } 33 + } 34 + 35 + fn max_joltage(bank: &[u32], n_battery: usize) -> u64 { 36 + let (res, _) = (0..n_battery).rev().fold((0, bank), |(acc, available), n| { 37 + let rev_pos = available.iter().rev().skip(n).position_max().unwrap() + n; 38 + let max_idx = available.len() - rev_pos - 1; 39 + let (max, rest) = available[max_idx..].split_first().unwrap(); 40 + (acc * 10 + *max as u64, rest) 41 + }); 42 + 43 + res 44 + } 45 + 46 + #[cfg(test)] 47 + mod tests { 48 + use super::*; 49 + 50 + const EXAMPLE_INPUT: &str = "\ 51 + 987654321111111 52 + 811111111111119 53 + 234234234234278 54 + 818181911112111"; 55 + 56 + const EXAMPLE_BANKS: [[u32; 15]; 4] = [ 57 + [9, 8, 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1], 58 + [8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9], 59 + [2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 7, 8], 60 + [8, 1, 8, 1, 8, 1, 9, 1, 1, 1, 1, 2, 1, 1, 1], 61 + ]; 62 + 63 + #[test] 64 + fn parse_example_input() { 65 + let Door { banks } = Door::parse(EXAMPLE_INPUT).unwrap(); 66 + itertools::assert_equal(banks, EXAMPLE_BANKS); 67 + } 68 + 69 + #[test] 70 + fn max_joltage_for_multiple_repeats() { 71 + assert_eq!(max_joltage(&[9, 9, 1], 2), 99); 72 + } 73 + 74 + #[test] 75 + fn example_max_joltages_of_2_batteries() { 76 + itertools::assert_equal(EXAMPLE_BANKS.map(|b| max_joltage(&b, 2)), [98, 89, 78, 92]); 77 + } 78 + 79 + #[test] 80 + fn example_max_joltages_of_12_batteries() { 81 + itertools::assert_equal( 82 + EXAMPLE_BANKS.map(|b| max_joltage(&b, 12)), 83 + [987654321111, 811111111119, 434234234278, 888911112111], 84 + ); 85 + } 86 + }
+2 -2
aoc_2025/src/main.rs
··· 2 2 3 3 mod day01; 4 4 mod day02; 5 - // mod day03; 5 + mod day03; 6 6 // mod day04; 7 7 // mod day05; 8 8 // mod day06; ··· 20 20 aoc_main(&[ 21 21 door!(2025-12-01 ~> day01), 22 22 door!(2025-12-02 ~> day02), 23 - // door!(2025-12-03 ~> day03), 23 + door!(2025-12-03 ~> day03), 24 24 // door!(2025-12-04 ~> day04), 25 25 // door!(2025-12-05 ~> day05), 26 26 // door!(2025-12-06 ~> day06),