Skip to content

Commit 2af09b2

Browse files
committed
refactor(14/2024): simplify math
1 parent f42e6a6 commit 2af09b2

File tree

4 files changed

+26
-52
lines changed

4 files changed

+26
-52
lines changed

src/solutions/year2024/day14.rs

Lines changed: 20 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::utils::point::Point;
44
use crate::utils::surface_range::SurfaceRange;
55
use itertools::Itertools;
66
use std::collections::HashSet;
7-
use std::ops::Neg;
87

98
pub struct Day14 {
109
surface: SurfaceRange,
@@ -13,10 +12,7 @@ pub struct Day14 {
1312
impl Solution for Day14 {
1413
fn part_one(&self, input: &str) -> String {
1514
let mut robots = self.parse(input);
16-
17-
for _ in 0..100 {
18-
robots = self.move_all(robots);
19-
}
15+
robots = self.move_all(robots, 100);
2016

2117
let start_x = self.surface.x().start();
2218
let end_x = self.surface.x().end();
@@ -48,7 +44,7 @@ impl Solution for Day14 {
4844
let mut second = 0;
4945
loop {
5046
second += 1;
51-
robots = self.move_all(robots);
47+
robots = self.move_all(robots, 1);
5248

5349
let points = robots.iter().map(|robot| robot.position()).collect_vec();
5450
let points: HashSet<Point> = HashSet::from_iter(points);
@@ -79,36 +75,18 @@ impl Day14 {
7975
.collect()
8076
}
8177

82-
fn move_robot(&self, moving_point: MovingPoint) -> MovingPoint {
83-
let mut next = moving_point.move_();
84-
85-
let y = self.surface.y();
86-
if y.is_before(next.position().y) {
87-
let teleport = y.end() - next.position().y.neg() + 1;
88-
89-
next = next.with_position_y(teleport);
90-
} else if y.is_after(next.position().y) {
91-
let teleport = y.start() + next.position().y - y.end() - 1;
78+
fn move_all(&self, robots: Vec<MovingPoint>, times: isize) -> Vec<MovingPoint> {
79+
robots
80+
.into_iter()
81+
.map(|r| {
82+
let new = r.position() + (r.velocity() * times);
9283

93-
next = next.with_position_y(teleport);
94-
}
95-
96-
let x = self.surface.x();
97-
if x.is_before(next.position().x) {
98-
let teleport = x.end() - next.position().x.neg() + 1;
84+
let x = new.x.rem_euclid(self.surface.x().len());
85+
let y = new.y.rem_euclid(self.surface.y().len());
9986

100-
next = next.with_position_x(teleport);
101-
} else if x.is_after(next.position().x) {
102-
let teleport = x.start() + next.position().x - x.end() - 1;
103-
104-
next = next.with_position_x(teleport);
105-
}
106-
107-
next
108-
}
109-
110-
fn move_all(&self, robots: Vec<MovingPoint>) -> Vec<MovingPoint> {
111-
robots.into_iter().map(|r| self.move_robot(r)).collect()
87+
r.with_position(Point::new(x, y))
88+
})
89+
.collect()
11290
}
11391
}
11492

@@ -148,22 +126,25 @@ p=9,5 v=-3,-3"#;
148126

149127
#[test]
150128
fn move_robot_example() {
151-
let solution = solution();
152129
let robot = MovingPoint::from((Point::new(2, 4), Point::new(2, -3)));
153130

154-
let robot = solution.move_robot(robot);
131+
let robot = move_robot(robot);
155132
assert_eq!(Point::new(4, 1), robot.position());
156133

157-
let robot = solution.move_robot(robot);
134+
let robot = move_robot(robot);
158135
assert_eq!(Point::new(6, 5), robot.position());
159136

160-
let robot = solution.move_robot(robot);
137+
let robot = move_robot(robot);
161138
assert_eq!(Point::new(8, 2), robot.position());
162139

163-
let robot = solution.move_robot(robot);
140+
let robot = move_robot(robot);
164141
assert_eq!(Point::new(10, 6), robot.position());
165142
}
166143

144+
fn move_robot(robot: MovingPoint) -> MovingPoint {
145+
solution().move_all(vec![robot], 1).pop().unwrap()
146+
}
147+
167148
fn solution() -> Day14 {
168149
Day14 {
169150
surface: SurfaceRange::from_points(0, 11 - 1, 0, 7 - 1),

src/utils/moving_point.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,8 @@ impl MovingPoint {
1111
self.position
1212
}
1313

14-
pub fn move_(&self) -> MovingPoint {
15-
Self {
16-
position: self.position + self.velocity,
17-
velocity: self.velocity,
18-
}
19-
}
20-
21-
pub fn with_position_y(&self, new_y: isize) -> Self {
22-
self.with_position(self.position().with_y(new_y))
23-
}
24-
25-
pub fn with_position_x(&self, new_x: isize) -> Self {
26-
self.with_position(self.position().with_x(new_x))
14+
pub fn velocity(&self) -> Point {
15+
self.velocity
2716
}
2817

2918
pub fn with_position(&self, position: Point) -> Self {

src/utils/point.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,12 @@ impl Point {
149149
((diff.x.abs().pow(2) + diff.y.abs().pow(2)) as f64).sqrt()
150150
}
151151

152+
#[allow(dead_code)]
152153
pub fn with_y(self, y: isize) -> Self {
153154
Self::new(self.x, y)
154155
}
155156

157+
#[allow(dead_code)]
156158
pub fn with_x(self, x: isize) -> Self {
157159
Self::new(x, self.y)
158160
}

src/utils/range.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,12 @@ impl Range {
9292
self.iter().collect::<Vec<isize>>().into_iter().rev()
9393
}
9494

95+
#[allow(dead_code)]
9596
pub fn is_before(&self, value: isize) -> bool {
9697
self.start > value
9798
}
9899

100+
#[allow(dead_code)]
99101
pub fn is_after(&self, value: isize) -> bool {
100102
self.end < value
101103
}

0 commit comments

Comments
 (0)