Skip to content

Commit 234b5ee

Browse files
committed
Solve day 24 puzzle part 2
1 parent 675bda2 commit 234b5ee

File tree

4 files changed

+221
-174
lines changed

4 files changed

+221
-174
lines changed

src/main/java/com/adventofcode/flashk/day24/Hailstone.java

Lines changed: 38 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22

33
import lombok.Getter;
44
import org.apache.commons.geometry.euclidean.threed.Vector3D;
5-
import org.apache.commons.geometry.euclidean.threed.line.Line3D;
6-
import org.apache.commons.geometry.euclidean.threed.line.Lines3D;
75
import org.apache.commons.lang3.StringUtils;
8-
import org.apache.commons.numbers.core.Precision;
6+
import org.apache.commons.math3.stat.regression.SimpleRegression;
97

108
public class Hailstone {
119

12-
private Vector3D position;
13-
private Vector3D speed;
14-
1510
@Getter
16-
private Line3D trajectory;
11+
private final Vector3D position;
1712

13+
@Getter
14+
private final Vector3D speed;
15+
16+
private final double slope; // m
17+
private final double intercept; // b
18+
1819
public Hailstone(String input, boolean isPartOne) {
1920
String[] inputParts = input.split("@");
2021
String[] posCoords = StringUtils.deleteWhitespace(inputParts[0]).split(",");
@@ -28,69 +29,63 @@ public Hailstone(String input, boolean isPartOne) {
2829
position = createVector3D(posCoords);
2930
speed = createVector3D(speedCoords);
3031

31-
//Precision.DoubleEquivalence equivalence = Precision.doubleEquivalenceOfEpsilon(1e-6);
32-
Precision.DoubleEquivalence equivalence = Precision.doubleEquivalenceOfEpsilon(1e-10);
32+
// Initialize slope and intercept
33+
Vector3D position2 = position.add(speed);
34+
35+
SimpleRegression simpleRegression = new SimpleRegression();
36+
simpleRegression.addData(position.getX(), position.getY());
37+
simpleRegression.addData(position2.getX(), position2.getY());
3338

34-
trajectory = Lines3D.fromPointAndDirection(position, speed, equivalence);
39+
slope = simpleRegression.getSlope();
40+
intercept = simpleRegression.getIntercept();
3541

3642
}
3743

3844
public boolean intersectsInFuture(Hailstone other, long min, long max) {
39-
Vector3D intersection = trajectory.intersection(other.trajectory);
4045

41-
// Parallel line
42-
if(intersection == null) {
43-
System.out.println("Hailstones's paths are parallel; they never intersect.");
44-
return false;
46+
if(slope == other.slope) {
47+
return false; // Hailstones' paths are parallel; they never intersect.
4548
}
4649

47-
// Check intersection in time
48-
boolean isInFutureA = isInFuture(intersection);
49-
boolean isInFutureB = other.isInFuture(intersection);
50+
// Calculate intersection
51+
double intersectX = (other.intercept - intercept) / (slope - other.slope);
52+
double intersectY = slope * intersectX + intercept;
5053

51-
if(!isInFutureA && !isInFutureB) {
52-
System.out.println("Hailstones' paths crossed in the past for both hailstones.");
53-
return false;
54-
} else if(!isInFutureA) {
55-
System.out.println("Hailstones' paths crossed in the past for hailstone A.");
56-
return false;
57-
} else if(!isInFutureB) {
58-
System.out.println("Hailstones' paths crossed in the past for hailstone B.");
59-
return false;
60-
}
54+
Vector3D intersection = Vector3D.of(intersectX, intersectY, 0);
6155

62-
boolean isInArea = isInArea(intersection, min, max);
63-
if(isInArea) {
64-
System.out.println("Hailstones' paths will cross inside the test area (at x="+intersection.getX()+", y="+intersection.getY()+").");
65-
} else {
66-
System.out.println("Hailstones' paths will cross outside the test area (at x="+intersection.getX()+", y="+intersection.getY()+").");
56+
// Intersection might have 4 different cases:
57+
// - Hailstones' paths crossed in the past for both hailstones. (false)
58+
// - Hailstones' paths crossed in the past for hailstone A. (false)
59+
// - Hailstones' paths crossed in the past for hailstone B. (false)
60+
// - Hailstones' paths cross in the future (true)
61+
if(isNotInFuture(intersection) || other.isNotInFuture(intersection)) {
62+
return false;
6763
}
6864

69-
return isInArea;
65+
// Two cases:
66+
// - Hailstones' paths cross inside the test area
67+
// - Hailstones' paths cross outisde the test area
68+
return isInArea(intersection, min, max);
7069
}
7170

7271
private Vector3D createVector3D(String[] coords) {
73-
return Vector3D.of(Double.valueOf(coords[0]), Double.valueOf(coords[1]), Double.valueOf(coords[2]));
72+
return Vector3D.of(Double.parseDouble(coords[0]), Double.parseDouble(coords[1]), Double.parseDouble(coords[2]));
7473
}
7574

76-
private boolean isInFuture(Vector3D intersection) {
75+
private boolean isNotInFuture(Vector3D intersection) {
7776

7877
double deltaX = intersection.getX() - position.getX();
7978
if((deltaX > 0 && speed.getX() < 0) || (deltaX < 0 && speed.getX() > 0)){
80-
return false;
79+
return true;
8180
}
8281

8382
double deltaY = intersection.getY() - position.getY();
8483
if((deltaY > 0 && speed.getY() < 0) || (deltaY < 0 && speed.getY() > 0)){
85-
return false;
84+
return true;
8685
}
8786

8887
double deltaZ = intersection.getZ() - position.getZ();
89-
if((deltaZ > 0 && speed.getZ() < 0) || (deltaZ < 0 && speed.getZ() > 0)){
90-
return false;
91-
}
92-
93-
return true;
88+
return (deltaZ > 0 && speed.getZ() < 0) || (deltaZ < 0 && speed.getZ() > 0);
9489
}
9590

9691
private boolean isInArea(Vector3D intersection, long min, long max){
@@ -99,9 +94,4 @@ private boolean isInArea(Vector3D intersection, long min, long max){
9994
intersection.getY() >= min &&
10095
intersection.getY() <= max;
10196
}
102-
103-
public boolean samePosition(Hailstone other) {
104-
return position.equals(other.position);
105-
}
106-
10797
}

src/main/java/com/adventofcode/flashk/day24/HailstoneRefactor.java

Lines changed: 0 additions & 107 deletions
This file was deleted.

0 commit comments

Comments
 (0)