Skip to content

Commit ad9e47b

Browse files
committed
perf(20/2024): optimize by calculate points without ranges
1 parent 687d376 commit ad9e47b

File tree

3 files changed

+21
-45
lines changed

3 files changed

+21
-45
lines changed

readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
| [Day 17: Chronospatial Computer](src/solutions/year2024/day17.rs) | - | - | - |
3131
| [Day 18: RAM Run](src/solutions/year2024/day18.rs) | ⭐⭐ | 2.487 | 204.885 |
3232
| [Day 19: Linen Layout](src/solutions/year2024/day19.rs) | ⭐⭐ | 2.923 | 22.751 |
33-
| [Day 20: Race Condition](src/solutions/year2024/day20.rs) | ⭐⭐ | 7.355 | 346.481 |
33+
| [Day 20: Race Condition](src/solutions/year2024/day20.rs) | ⭐⭐ | 7.355 | 280.627 |
3434

3535
# 2023
3636

src/solutions/year2024/day20.rs

-4
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ impl Solution for Day20 {
1414
}
1515

1616
fn part_two(&self, input: &str) -> String {
17-
// extract surface trait and contains method
18-
// grid has function get every position in area
19-
// rename surface range as rectangular area
20-
//
2117
self.part_two_cheats_in_range(input, 100..).to_string()
2218
}
2319
}

src/utils/deltoid_surface.rs

+20-40
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,32 @@
11
use crate::utils::point::Point;
2-
use crate::utils::range::Range;
3-
use std::collections::HashMap;
4-
5-
type Ranges = HashMap<isize, Range>;
62

73
pub struct DeltoidSurface {
84
#[allow(dead_code)]
95
point: Point,
106
#[allow(dead_code)]
117
distance: usize,
12-
#[allow(dead_code)]
13-
ranges: Ranges,
14-
points: Vec<Point>,
158
}
169

1710
impl DeltoidSurface {
1811
pub fn new(point: Point, distance: usize) -> Self {
19-
let ranges = Self::build_ranges(point, distance);
20-
let points = Self::build_points(&ranges);
21-
22-
Self {
23-
point,
24-
distance,
25-
ranges,
26-
points,
27-
}
12+
Self { point, distance }
2813
}
2914

3015
pub fn points(&self) -> Vec<Point> {
31-
self.points.clone()
32-
}
33-
34-
fn build_ranges(point: Point, distance: usize) -> Ranges {
35-
let isize_distance = distance as isize;
36-
37-
let mut ranges: Ranges = Ranges::with_capacity(distance * 2 + 1);
16+
let isize_distance = self.distance as isize;
17+
let required_capacity = (2 * self.distance.pow(2)) + 2 * self.distance + 1;
18+
let mut points: Vec<Point> = Vec::with_capacity(required_capacity);
3819

3920
for x in -isize_distance..=isize_distance {
4021
let height_diff = isize_distance - x.abs();
41-
let x = point.x + x;
42-
let y_range = Range::new(point.y - height_diff, point.y + height_diff).unwrap();
22+
let x = self.point.x + x;
4323

44-
ranges.insert(x, y_range);
24+
for y in self.point.y - height_diff..=self.point.y + height_diff {
25+
points.push(Point::new(x, y));
26+
}
4527
}
4628

47-
ranges
48-
}
49-
50-
fn build_points(ranges: &Ranges) -> Vec<Point> {
51-
ranges
52-
.iter()
53-
.flat_map(|(x, y_range)| {
54-
y_range
55-
.iter()
56-
.map(|y| Point::new(*x, y))
57-
.collect::<Vec<Point>>()
58-
})
59-
.collect()
29+
points
6030
}
6131
}
6232

@@ -95,8 +65,18 @@ mod tests {
9565
let surface = DeltoidSurface::new(middle, distance);
9666

9767
assert!(surface
98-
.points
68+
.points()
9969
.iter()
10070
.all(|p| p.manhattan_distance(&middle) <= distance as isize));
10171
}
72+
73+
#[test]
74+
fn points_count() {
75+
let middle = Point::new(4, 3);
76+
77+
assert_eq!(5, DeltoidSurface::new(middle, 1).points().len());
78+
assert_eq!(13, DeltoidSurface::new(middle, 2).points().len());
79+
assert_eq!(25, DeltoidSurface::new(middle, 3).points().len());
80+
assert_eq!(41, DeltoidSurface::new(middle, 4).points().len());
81+
}
10282
}

0 commit comments

Comments
 (0)