From a3a9eb0e45b525a279b0f114b3e8ad87a94c9b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Fri, 30 Jan 2026 20:04:20 +0100 Subject: [PATCH] Add solution for "Day 3: Lobby", part 2 --- README.md | 6 ++++++ src/solvers/lobby.rs | 35 ++++++++++++++++++++--------------- tests/examples.rs | 2 +- tests/full_data.rs | 2 +- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 43179c8..9ff3966 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,12 @@ Firstly, we calculate directly the sum of invalid IDs composed of two identical On top of that we use a cache to avoid recalculating prime factors and certain helper variables for given ID lengths and repetition counts. +### Day 3: Lobby + +:mag_right: Puzzle: , :white_check_mark: Solver: [`Lobby`](src/solvers/lobby.rs) + +With a continuously updated tally of the current best joltage initialized at zero, we go once through each digit string from left to right and try to maximize the digit with the highest posiible significance in our joltage as we go, as long as the less significant digits in the joltage are not more than what remains in the string. If a better digit was encountered, all less significant digits are reset to zero. + ### Day 4: Printing Department :mag_right: Puzzle: , :white_check_mark: Solver: [`PrintingDepartment`](src/solvers/printing_department.rs) diff --git a/src/solvers/lobby.rs b/src/solvers/lobby.rs index ff1f3b6..f721023 100644 --- a/src/solvers/lobby.rs +++ b/src/solvers/lobby.rs @@ -4,20 +4,24 @@ use std::io::BufRead; pub struct Lobby {} impl Lobby { - fn largest_joltage(bank: &str) -> u64 { - let mut best = (0, 0); - for d in bank.bytes().take(bank.len() - 1) { - if best.0 < d { - best = (d, 0) - } else if best.1 < d { - best.1 = d; + const PART1_MAX_BATTERIES: usize = 2; + const PART2_MAX_BATTERIES: usize = 12; + + fn largest_joltage(bank: &str, max_batteries: usize) -> u64 { + let mut best = vec![0_u8; max_batteries]; + for (i, d) in bank.bytes().map(|c| c - '0' as u8).enumerate() { + let mut fill_index = max_batteries; + let skip = (max_batteries + i).saturating_sub(bank.len()); + for (j, b) in best.iter_mut().skip(skip).enumerate() { + if *b < d { + *b = d; + fill_index = j + 1 + skip; + break; + } } + best[fill_index..].fill(0); } - let last = bank.bytes().last().unwrap(); - if best.1 < last { - best.1 = last; - } - u64::from((best.0 - '0' as u8) * 10 + (best.1 - '0' as u8)) + u64::from(best.iter().fold(0, |acc: u64, &x| acc * 10 + u64::from(x))) } } @@ -26,10 +30,11 @@ impl Solver for Lobby { const PUZZLE_NAME: &'static str = "Lobby"; fn process_data(&self, reader: R) -> (u64, u64) { - let mut joltage = 0; + let mut joltages = (0, 0); for line in reader.lines().map_while(Result::ok) { - joltage += Self::largest_joltage(&line); + joltages.0 += Self::largest_joltage(&line, Self::PART1_MAX_BATTERIES); + joltages.1 += Self::largest_joltage(&line, Self::PART2_MAX_BATTERIES); } - (joltage, 0) + joltages } } diff --git a/tests/examples.rs b/tests/examples.rs index 8f18a0b..6636784 100644 --- a/tests/examples.rs +++ b/tests/examples.rs @@ -27,7 +27,7 @@ fn gift_shop() { #[test] fn lobby() { assert_eq!( - Ok((357, 0)), + Ok((357, 3121910778619)), solvers::run_solver(solvers::lobby::Lobby {}, &EXAMPLE_PATHS) ); } diff --git a/tests/full_data.rs b/tests/full_data.rs index 3779ad8..08b3d3f 100644 --- a/tests/full_data.rs +++ b/tests/full_data.rs @@ -22,7 +22,7 @@ fn gift_shop() { #[test] fn lobby() { assert_eq!( - Ok((17144, 0)), + Ok((17144, 170371185255900)), solvers::run_solver(solvers::lobby::Lobby {}, &solvers::DATA_PATHS) ); }