From 7a3c36000c95c95bd956c8b21ea43da889142109 Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Wed, 3 Dec 2025 22:03:24 -0500 Subject: [PATCH] Solve day 3 --- README.md | 1 + src/day03/input/test1.txt | 4 ++ src/day03/mod.rs | 93 +++++++++++++++++++++++++++++++++++++++ src/days.rs | 1 + src/lib.rs | 1 + 5 files changed, 100 insertions(+) create mode 100644 src/day03/input/test1.txt create mode 100644 src/day03/mod.rs diff --git a/README.md b/README.md index 56c0aea..449beae 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,4 @@ Timings are given as: [lower-bound **best-estimate** upper-bound] |-----|--------|--------| | 01 | [101.34 µs **101.95 µs** 102.61 µs] | [105.90 µs **106.40 µs** 106.95 µs] | | 02 | [2.0990 ms **2.1113 ms** 2.1236 ms] | [2.0954 ms **2.1055 ms** 2.1157 ms] | +| 03 | [623.89 µs **631.99 µs** 641.14 µs] | [786.95 µs **793.43 µs** 800.13 µs] | diff --git a/src/day03/input/test1.txt b/src/day03/input/test1.txt new file mode 100644 index 0000000..7255fca --- /dev/null +++ b/src/day03/input/test1.txt @@ -0,0 +1,4 @@ +987654321111111 +811111111111119 +234234234234278 +818181911112111 diff --git a/src/day03/mod.rs b/src/day03/mod.rs new file mode 100644 index 0000000..7918d50 --- /dev/null +++ b/src/day03/mod.rs @@ -0,0 +1,93 @@ +use color_eyre::{Result, eyre::eyre}; +use tracing::{debug, instrument}; + +pub const INPUT: &str = include_str!("input/input.txt"); + +#[derive(Debug, Clone, Copy)] +struct Battery { + column: usize, + joltage: u32, +} + +impl Default for Battery { + fn default() -> Self { + Battery { + column: 0, + joltage: 0, + } + } +} + +fn largest_output_joltage(input: &str) -> Result { + let mut output_joltage: u64 = 0; + for (line_num, line) in input.trim().split('\n').enumerate() { + let mut batteries: [Battery; N] = [Battery::default(); N]; + let line_len = line.len(); + for (column, c) in line.bytes().enumerate() { + let joltage = (c as char).to_digit(10).ok_or_else(|| { + eyre!( + "Invalid character '{}' at line {}, column {}:\n {}\n {}^", + c as char, + line_num + 1, + column + 1, + line, + " ".repeat(column) + ) + })?; + let min = N.saturating_sub(line_len - column); + for i in min..N { + if joltage > batteries[i].joltage { + batteries[i].column = column; + batteries[i].joltage = joltage; + batteries[i + 1..].fill(Battery::default()); + break; + } + } + } + debug!(line, batteries = ?batteries.map(|b| b.joltage)); + output_joltage += batteries + .iter() + .fold(0u64, |acc, &b| acc * 10 + b.joltage as u64); + } + Ok(output_joltage) +} + +#[instrument(skip(input))] +pub fn part1(input: &str) -> Result { + largest_output_joltage::<2>(input) +} + +#[instrument(skip(input))] +pub fn part2(input: &str) -> Result { + largest_output_joltage::<12>(input) +} + +#[cfg(test)] +mod tests { + use super::*; + use test_log::test; + + const TEST_INPUT1: &str = include_str!("input/test1.txt"); + + #[test] + fn test_invalid_character_error() { + let input = "1234\n5678\n1234x678\n9012"; + let result = part1(input); + assert!(result.is_err()); + let error_msg = result.unwrap_err().to_string(); + assert_eq!( + error_msg, + "Invalid character 'x' at line 3, column 5:\n 1234x678\n ^" + ); + } + + #[test] + fn test_part1() { + assert_eq!(part1(TEST_INPUT1).unwrap(), 357); + } + + #[test] + fn test_part2() { + assert_eq!(part2(TEST_INPUT1).unwrap(), 3121910778619); + } +} diff --git a/src/days.rs b/src/days.rs index ec8584f..e3734d2 100644 --- a/src/days.rs +++ b/src/days.rs @@ -7,6 +7,7 @@ macro_rules! all_days { $macro_name! { 1 => day01, 2 => day02, + 3 => day03, } }; } diff --git a/src/lib.rs b/src/lib.rs index cd2013a..a000027 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ pub mod day01; pub mod day02; +pub mod day03; pub mod days;