|
1 | 1 | use crate::utils::point::Point;
|
2 |
| -use crate::utils::range::Range; |
3 |
| -use std::collections::HashMap; |
4 |
| - |
5 |
| -type Ranges = HashMap<isize, Range>; |
6 | 2 |
|
7 | 3 | pub struct DeltoidSurface {
|
8 | 4 | #[allow(dead_code)]
|
9 | 5 | point: Point,
|
10 | 6 | #[allow(dead_code)]
|
11 | 7 | distance: usize,
|
12 |
| - #[allow(dead_code)] |
13 |
| - ranges: Ranges, |
14 |
| - points: Vec<Point>, |
15 | 8 | }
|
16 | 9 |
|
17 | 10 | impl DeltoidSurface {
|
18 | 11 | 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 } |
28 | 13 | }
|
29 | 14 |
|
30 | 15 | 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); |
38 | 19 |
|
39 | 20 | for x in -isize_distance..=isize_distance {
|
40 | 21 | 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; |
43 | 23 |
|
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 | + } |
45 | 27 | }
|
46 | 28 |
|
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 |
60 | 30 | }
|
61 | 31 | }
|
62 | 32 |
|
@@ -95,8 +65,18 @@ mod tests {
|
95 | 65 | let surface = DeltoidSurface::new(middle, distance);
|
96 | 66 |
|
97 | 67 | assert!(surface
|
98 |
| - .points |
| 68 | + .points() |
99 | 69 | .iter()
|
100 | 70 | .all(|p| p.manhattan_distance(&middle) <= distance as isize));
|
101 | 71 | }
|
| 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 | + } |
102 | 82 | }
|
0 commit comments