diff --git a/Cargo.toml b/Cargo.toml index 79f1947..0e89dad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,7 @@ bstr = "1.11.0" clap = { version = "4.5.21", features = ["derive"] } color-eyre = "0.6.3" humantime = "2.1.0" + +[profile.release] +debug = true + diff --git a/src/bin/day2.rs b/src/bin/day2.rs index cc58b1b..1104722 100644 --- a/src/bin/day2.rs +++ b/src/bin/day2.rs @@ -1,4 +1,4 @@ -use std::time::Instant; +use std::{collections::HashSet, time::Instant}; use aoc_2025::{load, print_res}; use bstr::BString; @@ -27,6 +27,55 @@ pub fn parsing(input: &BString) -> color_eyre::Result> { .collect() } +fn id_sum(start: u64, end: u64, first_only: bool) -> u64 { + let mut sum = 0; + let mut seen = HashSet::new(); + + let mag = start.ilog10() + 1; + + assert_eq!( + mag, + end.ilog10() + 1, + "Only the same magnitude is supported" + ); + + for part_len in (1..mag) + .rev() + .filter(|&part_len| mag.is_multiple_of(part_len)) + { + let part_count = mag / part_len; + let pow_part = 10u64.pow(part_len); + + for part in (pow_part / 10)..pow_part { + let mut id = 0; + for _ in 0..part_count { + id = id * pow_part + part; + } + + if id < start { + continue; + } + + if id > end { + break; + } + + if seen.contains(&id) { + continue; + } + + seen.insert(id); + sum += id; + } + + if first_only { + break; + } + } + + sum +} + #[inline(never)] pub fn part1(input: Parsed) { let mut invalid_id_sum = 0; @@ -58,24 +107,7 @@ pub fn part1(input: Parsed) { panic!(); } - let half_mag = mag_s / 2; - let pow10 = 10u64.pow(half_mag); - - let high_start = s / pow10; - let high_end = e / pow10; - - for invalid_part in high_start..=high_end { - let invalid = invalid_part * pow10 + invalid_part; - if invalid < start { - continue - } - - if invalid > end { - break - } - - invalid_id_sum += invalid; - } + invalid_id_sum += id_sum(s, e, true); } print_res!("Sum of invalid IDs: {invalid_id_sum}"); @@ -83,7 +115,26 @@ pub fn part1(input: Parsed) { #[inline(never)] pub fn part2(input: Parsed) { - todo!("todo part2") + let mut invalid_id_sum = 0; + + for (start, end) in input { + let mut s = start; + let mag_e = end.ilog10() + 1; + loop { + let mag_s = s.ilog10() + 1; + + if mag_s != mag_e { + let next_start = 10u64.pow(mag_s); + invalid_id_sum += id_sum(s, next_start - 1, false); + s = next_start; + } else { + invalid_id_sum += id_sum(s, end, false); + break; + } + } + } + + print_res!("Sum of invalid IDs: {invalid_id_sum}"); } pub fn main() -> color_eyre::Result<()> {