diff --git a/README.md b/README.md index 1f35b56..e0ea6f0 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles. | 0.419 µs | 308.1 µs | | 53.39 µs | 28.44 µs | | 16.38 µs | 19.364 s | -| 0.513 µs | 2.463 ms | +| 0.513 µs | 0.650 µs | diff --git a/aoc2023/Cargo.toml b/aoc2023/Cargo.toml index 325df9a..e6104b9 100644 --- a/aoc2023/Cargo.toml +++ b/aoc2023/Cargo.toml @@ -16,6 +16,7 @@ aoc-runner-derive = { workspace = true } indoc = { workspace = true } itertools = { version = "0.12" } +num-integer = { version = "0.1" } rayon = { version = "1.8" } regex = { version = "1.10" } smallvec = { version = "1.11" } diff --git a/aoc2023/src/day6.rs b/aoc2023/src/day6.rs index 1fb66c7..f045908 100644 --- a/aoc2023/src/day6.rs +++ b/aoc2023/src/day6.rs @@ -26,6 +26,7 @@ mod utils { } impl RaceData { + /// Solver using brute force (faster than the quadratic formula for small inputs). pub fn n_record_breaks(&self) -> u64 { let (time, distance) = (self.time.parse().unwrap(), self.distance.parse().unwrap()); match (1..time).find(|j| j * (time - j) > distance) { @@ -34,6 +35,15 @@ mod utils { } } + /// Solver based on quadratic formula (much faster than brute force for large inputs). + pub fn n_record_breaks1(&self) -> u64 { + let (time, distance) = ( + self.time.parse::().unwrap(), + self.distance.parse::().unwrap(), + ); + 2 * num_integer::sqrt(time.pow(2) / 4 - distance - 1) + (time % 2) + 1 + } + pub fn merge(sequence: &[Self]) -> Self { let (time, distance) = sequence.iter().fold( Default::default(), @@ -53,7 +63,7 @@ fn part1(input: &[utils::RaceData]) -> u64 { #[aoc(day6, part2)] fn part2(input: &[utils::RaceData]) -> u64 { - utils::RaceData::merge(input).n_record_breaks() + utils::RaceData::merge(input).n_record_breaks1() } #[cfg(test)]