diff --git a/README.md b/README.md index 613a7aa..dade97e 100644 --- a/README.md +++ b/README.md @@ -27,17 +27,17 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www. | Day | Part 1 | Part 2 | | :---: | :---: | :---: | -| [Day 1](./src/bin/01.rs) | `32.6µs` | `35.8µs` | -| [Day 2](./src/bin/02.rs) | `42.6µs` | `41.4µs` | -| [Day 3](./src/bin/03.rs) | `84.2µs` | `99.7µs` | -| [Day 4](./src/bin/04.rs) | `49.5µs` | `49.7µs` | -| [Day 5](./src/bin/05.rs) | `20.7µs` | `24.1µs` | -| [Day 6](./src/bin/06.rs) | `194.0ns` | `102.0ns` | -| [Day 7](./src/bin/07.rs) | `96.3µs` | `92.1µs` | -| [Day 8](./src/bin/08.rs) | `73.4µs` | `161.1µs` | -| [Day 9](./src/bin/09.rs) | `51.8µs` | `47.9µs` | -| [Day 10](./src/bin/10.rs) | `394.6µs` | `788.1µs` | -| [Day 11](./src/bin/11.rs) | `16.4µs` | `15.8µs` | +| [Day 1](./src/bin/01.rs) | `34.2µs` | `38.0µs` | +| [Day 2](./src/bin/02.rs) | `42.3µs` | `41.3µs` | +| [Day 3](./src/bin/03.rs) | `83.6µs` | `99.8µs` | +| [Day 4](./src/bin/04.rs) | `53.5µs` | `50.4µs` | +| [Day 5](./src/bin/05.rs) | `20.8µs` | `24.3µs` | +| [Day 6](./src/bin/06.rs) | `203.0ns` | `103.0ns` | +| [Day 7](./src/bin/07.rs) | `93.8µs` | `91.4µs` | +| [Day 8](./src/bin/08.rs) | `72.7µs` | `161.5µs` | +| [Day 9](./src/bin/09.rs) | `58.5µs` | `50.6µs` | +| [Day 10](./src/bin/10.rs) | `394.2µs` | `775.3µs` | +| [Day 11](./src/bin/11.rs) | `16.1µs` | `15.7µs` | **Total: 2.22ms** diff --git a/src/bin/11.rs b/src/bin/11.rs index d276ba6..635e7d0 100644 --- a/src/bin/11.rs +++ b/src/bin/11.rs @@ -31,12 +31,12 @@ pub fn compute_expansion(input: &str, expansion_factor: u32) -> Option { // Now compute the sum of pairwise row differences and column differences // after expansion. Some( - compute_diff_sum(&row_counts, expansion_addition) - + compute_diff_sum(&col_counts, expansion_addition), + compute_diff_sum(row_counts, expansion_addition) + + compute_diff_sum(col_counts, expansion_addition), ) } -fn compute_diff_sum(counts: &[i32], expansion_addition: usize) -> u64 { +fn compute_diff_sum(counts: Vec, expansion_addition: usize) -> u64 { // This helper leverages an algebraic trick to turn the sum of distances // into a linear operation: // (x[i] - x[0]) + (x[i] - x[1]) + ... + (x[i] - x[i-1]) = @@ -56,9 +56,14 @@ fn compute_diff_sum(counts: &[i32], expansion_addition: usize) -> u64 { let mut total_sum = 0; let mut offset = 0; let mut galaxy_index = 0; - for (i, c) in counts.iter().copied().enumerate() { + for (i, c) in counts.into_iter().enumerate() { let expanded_rowcol_index = i + offset; for _ in 0..c { + // NOTE: it's possible to remove this for loop by doing more algebra here, + // but the benchmark is only ~200ns faster due to the counts being rather + // small for most rows and columns, and the code is significantly less readable + // with the optimized version. If the inputs were very large, though, it could + // help. difference_sum += galaxy_index * expanded_rowcol_index - total_sum; total_sum += expanded_rowcol_index; galaxy_index += 1; @@ -66,6 +71,16 @@ fn compute_diff_sum(counts: &[i32], expansion_addition: usize) -> u64 { if c == 0 { offset += expansion_addition; } + // Optimized, but unreadable version: + // if c > 0 { + // let n = c as usize; + // difference_sum += (n * galaxy_index + n * (n - 1) / 2) * expanded_rowcol_index + // - (n * total_sum + (n - 1) * expanded_rowcol_index); + // total_sum += n * expanded_rowcol_index; + // galaxy_index += n; + // } else { + // offset += expansion_addition; + // } } difference_sum as u64 }