11package dev .vinyard .adventofcode .soluce .year2023 .day24 ;
22
3+ import org .apache .commons .lang3 .tuple .Pair ;
34import org .apache .commons .math3 .linear .*;
45
56import java .util .List ;
7+ import java .util .stream .IntStream ;
68
79public class ASD {
810
@@ -16,170 +18,106 @@ public Root(List<Hail> hails, Bounds bounds) {
1618 }
1719
1820 public Long getCollisionsCountInBounds () {
19- long count = 0 ;
20-
21- for (int i = 0 ; i < hails .size (); i ++) {
22- for (int j = i + 1 ; j < hails .size (); j ++) {
23- Hail first = hails .get (i );
24- Hail second = hails .get (j );
25-
26- if (getHailCollisionPosition (first , second )) {
27- count ++;
28- }
29- }
30- }
31-
32- return count ;
21+ return IntStream .range (0 , hails .size ()).boxed ()
22+ .flatMap (i -> IntStream .range (i + 1 , hails .size ()).mapToObj (j -> Pair .of (hails .get (i ), hails .get (j ))))
23+ .filter (this ::getHailCollisionPosition )
24+ .count ();
3325 }
3426
3527 public Long findRockPositionScore () {
3628 Position rockPosition = findRockPosition (hails );
37- System .out .println ("%s, %s, %s" .formatted (rockPosition .x , rockPosition .y , rockPosition .z ));
3829 return (long ) (rockPosition .x + rockPosition .y + rockPosition .z );
3930 }
4031
41- public boolean getHailCollisionPosition (Hail first , Hail second ) {
42- double a1 = first .a ();
43- double b1 = first .b ();
44- double c1 = first .c ();
32+ public boolean getHailCollisionPosition (Pair <Hail , Hail > pair ) {
33+ Hail h1 = pair .getLeft ();
34+ Hail h2 = pair .getRight ();
35+
36+ double a1 = h1 .a ();
37+ double b1 = h1 .b ();
38+ double c1 = h1 .c ();
4539
46- double a2 = second .a ();
47- double b2 = second .b ();
48- double c2 = second .c ();
40+ double a2 = h2 .a ();
41+ double b2 = h2 .b ();
42+ double c2 = h2 .c ();
4943
50- if (a1 * b2 == a2 * b1 )
51- return false ; // Parallel lines
44+ if (a1 * b2 == a2 * b1 ) return false ; // Parallel lines
5245
5346 double x = (c1 * b2 - c2 * b1 ) / (a1 * b2 - a2 * b1 );
5447 double y = (c1 * a2 - c2 * a1 ) / (a2 * b1 - a1 * b2 );
5548
56- if (first .velocity .x * (x - first .position .x ) < 0 || first .velocity .y * (y - first .position .y ) < 0 )
49+ if (h1 .velocity .x * (x - h1 .position .x ) < 0 || h1 .velocity .y * (y - h1 .position .y ) < 0 )
5750 return false ; // In the past
5851
59- if (second .velocity .x * (x - second .position .x ) < 0 || second .velocity .y * (y - second .position .y ) < 0 )
52+ if (h2 .velocity .x * (x - h2 .position .x ) < 0 || h2 .velocity .y * (y - h2 .position .y ) < 0 )
6053 return false ; // In the past
6154
6255 return bounds .contains (x ) && bounds .contains (y );
6356 }
6457
6558 public Position findRockPosition (List <Hail > hails ) {
66- // Nous avons besoin d'au moins 4 grêlons pour résoudre complètement (6 inconnues)
67- if (hails .size () < 4 ) {
68- throw new IllegalArgumentException ("Au moins 4 grêlons sont nécessaires" );
69- }
59+ if (hails .size () < 4 )
60+ throw new IllegalArgumentException ("At least 3 hailstones are required to determine the rock's position and velocity." );
7061
71- // Construire un système avec 6 équations pour 6 inconnues (xr, yr, zr, vxr, vyr, vzr)
62+ // Building a system with 6 equations for 6 unknowns (xr, yr, zr, vxr, vyr, vzr)
7263 double [][] matrixData = new double [6 ][6 ];
7364 double [] vectorData = new double [6 ];
7465
75- // Utilisons 3 paires de grêlons pour construire notre système
66+ // Use the first three pairs of hailstones to build our system
7667 Hail h0 = hails .get (0 );
7768 Hail h1 = hails .get (1 );
7869 Hail h2 = hails .get (2 );
7970 Hail h3 = hails .get (3 );
8071
81- // Pour chaque paire de grêlons, nous créons 2 équations
82- // Premier hailstone - équations de collision en x,y
83- setupEquations (h0 , h1 , 0 , matrixData , vectorData );
72+ setupEquations ( Pair . of ( h0 , h1 ), 0 , matrixData , vectorData );
73+ setupEquations ( Pair . of ( h1 , h2 ), 2 , matrixData , vectorData );
74+ setupEquations (Pair . of ( h2 , h3 ), 4 , matrixData , vectorData );
8475
85- // Deuxième paire - équations de collision en y,z
86- setupEquations (h1 , h2 , 2 , matrixData , vectorData );
87-
88- // Troisième paire - équations en x,z
89- setupEquations (h2 , h3 , 4 , matrixData , vectorData );
90-
91- // Résoudre le système avec Commons Math
76+ // Solving the system using Apache Commons Math
9277 RealMatrix coefficients = new Array2DRowRealMatrix (matrixData , false );
9378 DecompositionSolver solver = new LUDecomposition (coefficients ).getSolver ();
9479
95- if (!solver .isNonSingular ()) {
96- throw new IllegalStateException ("Le système n'a pas de solution unique" );
97- }
98-
9980 RealVector constants = new ArrayRealVector (vectorData , false );
10081 RealVector solution = solver .solve (constants );
10182
102- // Extraire la position de la solution
103- double xr = solution .getEntry (0 );
104- double yr = solution .getEntry (1 );
105- double zr = solution .getEntry (2 );
106- double vxr = solution .getEntry (3 );
107- double vyr = solution .getEntry (4 );
108- double vzr = solution .getEntry (5 );
109-
110-
111- // Vérification avec un 5ème grêlon si disponible
112- if (hails .size () > 4 ) {
113- Hail h4 = hails .get (4 );
114-
115- // Calculer le temps d'intersection
116- double tx = Double .NaN ;
117- double ty = Double .NaN ;
118- double tz = Double .NaN ;
119-
120- if (vxr != h4 .velocity ().x ) {
121- tx = (h4 .position ().x - xr ) / (vxr - h4 .velocity ().x );
122- }
123-
124- if (vyr != h4 .velocity ().y ) {
125- ty = (h4 .position ().y - yr ) / (vyr - h4 .velocity ().y );
126- }
127-
128- if (vzr != h4 .velocity ().z ) {
129- tz = (h4 .position ().z - zr ) / (vzr - h4 .velocity ().z );
130- }
131-
132- System .out .println ("Vérification avec le 5ème grêlon - temps: tx=" + tx + ", ty=" + ty + ", tz=" + tz );
133-
134- // Vérifier que les points d'intersection correspondent
135- double x5 = xr + vxr * tx ;
136- double y5 = yr + vyr * ty ;
137- double z5 = zr + vzr * tz ;
138-
139- double x5_hail = h4 .position ().x + h4 .velocity ().x * tx ;
140- double y5_hail = h4 .position ().y + h4 .velocity ().y * ty ;
141- double z5_hail = h4 .position ().z + h4 .velocity ().z * tz ;
142-
143- System .out .println ("Position calculée du point d'intersection: " + x5 + ", " + y5 + ", " + z5 );
144- System .out .println ("Position attendue du point d'intersection: " + x5_hail + ", " + y5_hail + ", " + z5_hail );
145- }
146-
83+ double xr = Math .round (solution .getEntry (0 ));
84+ double yr = Math .round (solution .getEntry (1 ));
85+ double zr = Math .round (solution .getEntry (2 ));
14786
14887 return new Position (xr , yr , zr );
14988 }
15089
151- private void setupEquations (Hail h1 , Hail h2 , int startRow , double [][] matrix , double [] vector ) {
152- // Pour la paire de hailstones h1 et h2, nous créons 2 équations
90+ private void setupEquations (Pair <Hail , Hail > pair , int startRow , double [][] matrix , double [] vector ) {
91+ Hail h1 = pair .getLeft ();
92+ Hail h2 = pair .getRight ();
15393
154- // Équation 1: basée sur le plan formé par les trajectoires en x,y
94+ // For the pair of hailstones h1 and h2, we create 2 equations
95+
96+ // Equation 1: based on the plane formed by the trajectories in x,y
15597 // (xr - x1) * (vy1 - vyr) - (yr - y1) * (vx1 - vxr) = 0
15698 // (xr - x2) * (vy2 - vyr) - (yr - y2) * (vx2 - vxr) = 0
157- // En soustrayant ces équations, on obtient une équation linéaire
158-
159- matrix [startRow ][0 ] = h1 .velocity ().y - h2 .velocity ().y ; // coefficient de xr
160- matrix [startRow ][1 ] = h2 .velocity ().x - h1 .velocity ().x ; // coefficient de yr
161- matrix [startRow ][2 ] = 0 ; // coefficient de zr
162- matrix [startRow ][3 ] = h2 .position ().y - h1 .position ().y ; // coefficient de vxr
163- matrix [startRow ][4 ] = h1 .position ().x - h2 .position ().x ; // coefficient de vyr
164- matrix [startRow ][5 ] = 0 ; // coefficient de vzr
99+ // By subtracting these equations, we get a linear equation
100+ matrix [startRow ][0 ] = h1 .velocity ().y - h2 .velocity ().y ; // coefficient of xr
101+ matrix [startRow ][1 ] = h2 .velocity ().x - h1 .velocity ().x ; // coefficient of yr
102+ matrix [startRow ][2 ] = 0 ; // coefficient of zr
103+ matrix [startRow ][3 ] = h2 .position ().y - h1 .position ().y ; // coefficient of vxr
104+ matrix [startRow ][4 ] = h1 .position ().x - h2 .position ().x ; // coefficient of vyr
105+ matrix [startRow ][5 ] = 0 ; // coefficient of vzr
165106
166- vector [startRow ] = h1 .position ().x * h1 .velocity ().y - h1 .position ().y * h1 .velocity ().x
167- - h2 .position ().x * h2 .velocity ().y + h2 .position ().y * h2 .velocity ().x ;
107+ vector [startRow ] = h1 .position ().x * h1 .velocity ().y - h1 .position ().y * h1 .velocity ().x - h2 .position ().x * h2 .velocity ().y + h2 .position ().y * h2 .velocity ().x ;
168108
169- // Équation 2: basée sur le plan formé par les trajectoires en y,z
109+ // Equation 2: based on the plane formed by the trajectories in y,z
170110 // (yr - y1) * (vz1 - vzr) - (zr - z1) * (vy1 - vyr) = 0
171111 // (yr - y2) * (vz2 - vzr) - (zr - z2) * (vy2 - vyr) = 0
172- // En soustrayant ces équations, on obtient une équation linéaire
173-
174- matrix [startRow +1 ][0 ] = 0 ; // coefficient de xr
175- matrix [startRow +1 ][1 ] = h1 .velocity ().z - h2 .velocity ().z ; // coefficient de yr
176- matrix [startRow +1 ][2 ] = h2 .velocity ().y - h1 .velocity ().y ; // coefficient de zr
177- matrix [startRow +1 ][3 ] = 0 ; // coefficient de vxr
178- matrix [startRow +1 ][4 ] = h2 .position ().z - h1 .position ().z ; // coefficient de vyr
179- matrix [startRow +1 ][5 ] = h1 .position ().y - h2 .position ().y ; // coefficient de vzr
180-
181- vector [startRow +1 ] = h1 .position ().y * h1 .velocity ().z - h1 .position ().z * h1 .velocity ().y
182- - h2 .position ().y * h2 .velocity ().z + h2 .position ().z * h2 .velocity ().y ;
112+ // By subtracting these equations, we get a linear equation
113+ matrix [startRow + 1 ][0 ] = 0 ; // coefficient of xr
114+ matrix [startRow + 1 ][1 ] = h1 .velocity ().z - h2 .velocity ().z ; // coefficient of yr
115+ matrix [startRow + 1 ][2 ] = h2 .velocity ().y - h1 .velocity ().y ; // coefficient of zr
116+ matrix [startRow + 1 ][3 ] = 0 ; // coefficient of vxr
117+ matrix [startRow + 1 ][4 ] = h2 .position ().z - h1 .position ().z ; // coefficient of vyr
118+ matrix [startRow + 1 ][5 ] = h1 .position ().y - h2 .position ().y ; // coefficient of vzr
119+
120+ vector [startRow + 1 ] = h1 .position ().y * h1 .velocity ().z - h1 .position ().z * h1 .velocity ().y - h2 .position ().y * h2 .velocity ().z + h2 .position ().z * h2 .velocity ().y ;
183121 }
184122
185123 }
@@ -203,23 +141,12 @@ public double b() {
203141 public double c () {
204142 return velocity .x * position .y - velocity .y * position .x ;
205143 }
206-
207- @ Override
208- public String toString () {
209- return "%s @ %s" .formatted (position , velocity );
210- }
211144 }
145+
212146 public record Position (double x , double y , double z ) {
213- @ Override
214- public String toString () {
215- return "%s, %s, %s" .formatted (x , y , z );
216- }
217147 }
148+
218149 public record Velocity (double x , double y , double z ) {
219- @ Override
220- public String toString () {
221- return "%s, %s, %s" .formatted (x , y , z );
222- }
223150 }
224151
225152}
0 commit comments