Skip to content

Commit 7ea71b6

Browse files
committed
Speed things up by caching slow GCD calculation
1 parent 1532176 commit 7ea71b6

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ Performance is reasonable even on older hardware, for example a 2011 MacBook Pro
244244
| 7 | [Amplification Circuit](https://adventofcode.com/2019/day/7) | [Source](src/year2019/day07.rs) | 79 |
245245
| 8 | [Space Image Format](https://adventofcode.com/2019/day/8) | [Source](src/year2019/day08.rs) | 4 |
246246
| 9 | [Sensor Boost](https://adventofcode.com/2019/day/9) | [Source](src/year2019/day09.rs) | 1008 |
247-
| 10 | [Monitoring Station](https://adventofcode.com/2019/day/10) | [Source](src/year2019/day10.rs) | 1092 |
247+
| 10 | [Monitoring Station](https://adventofcode.com/2019/day/10) | [Source](src/year2019/day10.rs) | 404 |
248248
| 11 | [Space Police](https://adventofcode.com/2019/day/11) | [Source](src/year2019/day11.rs) | 320 |
249249
| 12 | [The N-Body Problem](https://adventofcode.com/2019/day/12) | [Source](src/year2019/day12.rs) | 838 |
250250
| 13 | [Care Package](https://adventofcode.com/2019/day/13) | [Source](src/year2019/day13.rs) | 2527 |

src/year2019/day10.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,49 +46,58 @@
4646
//! sorting a second time in this order.
4747
//!
4848
//! [`atan2`]: f64::atan2
49+
use crate::util::grid::*;
4950
use crate::util::math::*;
5051
use crate::util::point::*;
5152
use std::cmp::Ordering;
5253

5354
type Input = (i32, i32);
5455

5556
pub fn parse(input: &str) -> Input {
56-
let raw: Vec<_> = input.lines().map(str::as_bytes).collect();
57-
let width = raw[0].len() as i32;
58-
let height = raw.len() as i32;
57+
let grid = Grid::parse(input);
58+
let width = grid.width;
59+
let height = grid.height;
5960

6061
// Convert asteroids to `Point` objects.
6162
let mut points = Vec::new();
6263

63-
for (y, row) in raw.iter().enumerate() {
64-
for (x, &col) in row.iter().enumerate() {
65-
if col == b'#' {
66-
points.push(Point::new(x as i32, y as i32));
64+
for y in 0..height {
65+
for x in 0..width {
66+
let point = Point::new(x, y);
67+
if grid[point] == b'#' {
68+
points.push(point);
6769
}
6870
}
6971
}
7072

7173
// Find asteroid with the highest visibility.
74+
let mut seen = Grid::new(2 * width, 2 * height, 0);
75+
let mut cache = grid.same_size_with(0);
7276
let mut visible = vec![0; points.len()];
73-
let mut seen = vec![0; (4 * width * height) as usize];
7477
let mut max_visible = 0;
7578
let mut max_index = 0;
7679

7780
for i in 0..(points.len() - 1) {
7881
for j in (i + 1)..points.len() {
79-
let mut delta = points[j] - points[i];
82+
let delta = points[j] - points[i];
83+
let key = Point::new(delta.x.abs(), delta.y.abs());
84+
85+
let gcd = if cache[key] > 0 {
86+
cache[key]
87+
} else {
88+
cache[key] = key.x.gcd(key.y);
89+
cache[key]
90+
};
8091

8192
// Key insight is that points on the same line are integer multiples of each other.
82-
let factor = delta.x.gcd(delta.y).abs();
83-
delta.x /= factor;
84-
delta.y /= factor;
93+
let adjusted = Point::new(delta.x / gcd, delta.y / gcd);
8594

8695
// This works as the points are in order from left to right and top to bottom,
8796
// so we process points from nearest to furthest.
88-
let index = (2 * width) * (height + delta.y) + (width + delta.x);
97+
let index = Point::new(width + adjusted.x, height + adjusted.y);
8998

90-
if seen[index as usize] <= i {
91-
seen[index as usize] = i + 1;
99+
if seen[index] <= i {
100+
seen[index] = i + 1;
92101
visible[i] += 1;
93102
visible[j] += 1;
94103
}

0 commit comments

Comments
 (0)