diff --git a/aoc2025/src/day02.rs b/aoc2025/src/day02.rs index dfa960e..5b99438 100644 --- a/aoc2025/src/day02.rs +++ b/aoc2025/src/day02.rs @@ -6,6 +6,7 @@ const INPUT: &str = include_str!("../input/day02.txt"); pub fn run() -> Result { let mut res = String::with_capacity(128); writeln!(res, "part 1: {}", part1(INPUT)?)?; + writeln!(res, "part 2: {}", part2(INPUT)?)?; Ok(res) } @@ -88,6 +89,54 @@ fn part1(input: &str) -> Result { .sum()) } +fn has_identical_chunks(num: &u64, chunk_size: usize) -> bool { + // build a "mask" for our chunk size + let mask = 10_u64.pow(chunk_size as u32); + + // this is what all chunks should look like to satisfy our condition + let target = *num % mask; + + let mut num = *num; + while num > target { + // shift num right by 10^(sub_digit_num) + num /= mask; + if num % mask != target { + return false; + } + } + + true +} + +fn is_repeated_at_least_twice(num: &u64) -> bool { + let num_digits = get_num_digits(num); + if num_digits < 2 { + return false; + } + + has_identical_chunks(num, 1) + || (2..=(num_digits / 2)).any(|n| { + // walk all possible divisors of our number of digits + if !num_digits.is_multiple_of(n) { + return false; + } + let chunk_size = num_digits / n; + has_identical_chunks(num, chunk_size) + }) +} + +fn part2(input: &str) -> Result { + let ranges = input + .split(',') + .map(IdRange::from_str) + .collect::>>()?; + + Ok(ranges + .into_iter() + .map(|range| range.filter(is_repeated_at_least_twice).sum::()) + .sum()) +} + #[cfg(test)] mod tests { use super::*; @@ -120,13 +169,34 @@ mod tests { assert_eq!(part1(INPUT).unwrap(), 26255179562); } - //#[test] - //fn part2_provided() { - // assert_eq!(part2(PROVIDED).unwrap(), 6); - //} + #[test] + fn repeated_at_least_twice() { + assert!(is_repeated_at_least_twice(&11)); + assert!(is_repeated_at_least_twice(&22)); + assert!(is_repeated_at_least_twice(&99)); + assert!(is_repeated_at_least_twice(&111)); + assert!(is_repeated_at_least_twice(&999)); + assert!(is_repeated_at_least_twice(&1010)); + assert!(is_repeated_at_least_twice(&1188511885)); + assert!(is_repeated_at_least_twice(&222222)); + assert!(is_repeated_at_least_twice(&446446)); + assert!(is_repeated_at_least_twice(&38593859)); + assert!(is_repeated_at_least_twice(&565656)); + assert!(is_repeated_at_least_twice(&824824824)); + assert!(is_repeated_at_least_twice(&2121212121)); - //#[test] - //fn part2_real() { - // assert_eq!(part2(INPUT).unwrap(), 6616); - //} + assert!(!is_repeated_at_least_twice(&1121)); + assert!(!is_repeated_at_least_twice(&121)); + assert!(!is_repeated_at_least_twice(&1)); + } + + #[test] + fn part2_provided() { + assert_eq!(part2(PROVIDED).unwrap(), 4174379265); + } + + #[test] + fn part2_real() { + assert_eq!(part2(INPUT).unwrap(), 31680313976); + } }