diff --git a/src/day2.rs b/src/day2.rs index 04b3447..c3d0508 100644 --- a/src/day2.rs +++ b/src/day2.rs @@ -103,6 +103,36 @@ fn part2_arithmetic_brute(input: &[RangeInclusive]) -> u64 { invalid_sum } +#[aoc(day2, part1, Clever)] +fn part1_clever(input: &[RangeInclusive]) -> u64 { + let mut invalid_sum = 0; + for r in input { + let n_digits = r.start().ilog10() + 1; + + let mut lhs = if n_digits % 2 != 0 { + // If the number of digits is odd, we start our guess at the first possibility in the next decade + 10u64.pow(n_digits / 2) + } else { + let start_decade = 10u64.pow(n_digits / 2); + r.start() / start_decade + }; + + // we will guess the next repeater, and check if it's in range, if not we are done. + loop { + let repeater = lhs * 10u64.pow(lhs.ilog10() + 1) + lhs; + if repeater < *r.start() { + lhs += 1 + } else if r.contains(&repeater) { + invalid_sum += repeater; + lhs += 1 + } else { + break; + } + } + } + invalid_sum +} + #[cfg(test)] mod tests { use super::*; @@ -127,4 +157,8 @@ mod tests { fn part2_arithmetic_example() { assert_eq!(part2_arithmetic_brute(&parse(EXAMPLE)), 1227775554); } + #[test] + fn part1_clever_example() { + assert_eq!(part1_clever(&parse(EXAMPLE)), 1227775554); + } }