66
77@ Solution (
88 id = 20250901 ,
9- name = "Day 9: " ,
9+ name = "Day 9: Movie Theater " ,
1010 url = "https://adventofcode.com/2025/day/9" ,
11- category = "2025" ,
12- solved = false )
11+ category = "2025" )
1312@ Solution (
1413 id = 20250902 ,
15- name = "Day 9: - Part 2" ,
14+ name = "Day 9: Movie Theater - Part 2" ,
1615 url = "https://adventofcode.com/2025/day/9#part2" ,
17- category = "2025" ,
18- solved = false )
16+ category = "2025" )
1917public class Day09 extends AOCSolution {
2018
2119 @ Override
@@ -27,83 +25,36 @@ protected void runPartOne(final Scanner in) {
2725 protected void runPartTwo (final Scanner in ) {
2826 run (
2927 in ,
30- (current , other , boundingLines ) -> {
28+ (current , other , lines ) -> {
3129 final long minX = Math .min (current .x , other .x );
3230 final long maxX = Math .max (current .x , other .x );
3331 final long minY = Math .min (current .y , other .y );
3432 final long maxY = Math .max (current .y , other .y );
3533
36- final Line topLine = new Line (new Coordinate (minX , minY ), new Coordinate (maxX , minY ));
37- final Line bottomLine = new Line (new Coordinate (minX , maxY ), new Coordinate (maxX , maxY ));
38- final Line leftLine = new Line (new Coordinate (minX , minY ), new Coordinate (minX , maxY ));
39- final Line rightLine = new Line (new Coordinate (maxX , minY ), new Coordinate (maxX , maxY ));
40-
41- return boundingLines .stream ()
42- .anyMatch (
43- line ->
44- topLine .intersectsTopLine (line )
45- || bottomLine .intersectsBottomLine (line )
46- || leftLine .intersectsLeftLine (line )
47- || rightLine .intersectsRightLine (line ));
48-
49- /*
50- final Coordinate topCorner =
51- current.y < other.y
52- ? new Coordinate(other.x, current.y)
53- : new Coordinate(current.x, other.y);
54- final Coordinate bottomCorner =
55- current.y >= other.y
56- ? new Coordinate(other.x, current.y)
57- : new Coordinate(current.x, other.y);
58-
59- final boolean allPointsInside =
60- isInsideBelow(topCorner, boundingLines) && isInsideAbove(bottomCorner, boundingLines);
61-
62- if (!allPointsInside) {
34+ final Line top =
35+ new Line (new Coordinate (minX + 1 , minY + 1 ), new Coordinate (maxX - 1 , minY + 1 ));
36+ final Line bottom =
37+ new Line (new Coordinate (minX + 1 , maxY - 1 ), new Coordinate (maxX - 1 , maxY - 1 ));
38+ if (lines .stream ().anyMatch (top ::intersects )
39+ || lines .stream ().anyMatch (bottom ::intersects )) {
6340 return false ;
6441 }
6542
66- return true;
67-
68- /*
69- for (long x = Math.min(current.x, other.x) + 1; x < Math.max(current.x, other.x); ++x) {
70- if (!isInside(new Coordinate(x, current.y), boundingLines)
71- || !isInside(new Coordinate(x, other.y), boundingLines)) {
72- return false;
73- }
74- }
75-
76- for (long y = Math.min(current.y, other.y) + 1; y < Math.max(current.y, other.y); ++y) {
77- if (!isInside(new Coordinate(current.x, y), boundingLines)
78- || !isInside(new Coordinate(other.x, y), boundingLines)) {
79- return false;
80- }
43+ final Line left =
44+ new Line (new Coordinate (minX + 1 , minY + 1 ), new Coordinate (minX + 1 , maxY - 1 ));
45+ final Line right =
46+ new Line (new Coordinate (maxX - 1 , minY + 1 ), new Coordinate (maxX - 1 , maxY - 1 ));
47+ if (lines .stream ().anyMatch (left ::intersects )
48+ || lines .stream ().anyMatch (right ::intersects )) {
49+ return false ;
8150 }
8251
8352 return true ;
84-
85- /*final Set<Line> rectangle =
86- Set.of(
87- new Line(current, corner1),
88- new Line(current, corner2),
89- new Line(other, corner1),
90- new Line(other, corner2));
91-
92- for (final Line side : rectangle) {
93- for (final Line boundingLine : boundingLines) {
94- if (side.reallyIntersects(boundingLine)) {
95- return false;
96- }
97- }
98- }
99-
100- return true;*/
10153 });
10254 }
10355
104- private void run (final Scanner in , final TriPredicate validityChecker ) {
56+ private void run (final Scanner in , final ValidityChecker validityChecker ) {
10557 final List <Coordinate > tiles = new ArrayList <>();
106- long maxArea = 0 ;
10758
10859 while (in .hasNextLine ()) {
10960 final String [] line = in .nextLine ().split ("," );
@@ -115,12 +66,9 @@ private void run(final Scanner in, final TriPredicate validityChecker) {
11566 lines .add (new Line (tiles .get (i ), tiles .get ((i + 1 ) % tiles .size ())));
11667 }
11768
118- for (int i = 0 ; i < tiles .size (); ++i ) {
119- final Coordinate current = tiles .get (i );
120-
121- for (int j = i + 1 ; j < tiles .size (); ++j ) {
122- final Coordinate other = tiles .get (j );
123-
69+ long maxArea = 0 ;
70+ for (final Coordinate current : tiles ) {
71+ for (final Coordinate other : tiles ) {
12472 final long area = (1 + Math .abs (other .x - current .x )) * (1 + Math .abs (other .y - current .y ));
12573 if (area > maxArea && validityChecker .apply (current , other , lines )) {
12674 maxArea = area ;
@@ -131,100 +79,31 @@ private void run(final Scanner in, final TriPredicate validityChecker) {
13179 print (maxArea );
13280 }
13381
134- private boolean isInsideBelow (final Coordinate point , final List <Line > boundingLines ) {
135- final Line ray = new Line (point , new Coordinate (100000 , point .y ));
136-
137- return boundingLines .stream ().filter (ray ::intersectsRayBelow ).count () % 2 == 1 ;
138- }
139-
140- private boolean isInsideAbove (final Coordinate point , final List <Line > boundingLines ) {
141- final Line ray = new Line (point , new Coordinate (100000 , point .y ));
142-
143- return boundingLines .stream ().filter (ray ::intersectsRayAbove ).count () % 2 == 1 ;
144- }
145-
146- private interface TriPredicate {
147- boolean apply (Coordinate tile1 , Coordinate tile2 , List <Line > lines );
82+ private interface ValidityChecker {
83+ boolean apply (Coordinate tile1 , Coordinate tile2 , final List <Line > lines );
14884 }
14985
15086 private record Coordinate (long x , long y ) {}
15187
15288 private record Line (Coordinate start , Coordinate end ) {
153- public boolean intersectsTopLine (final Line other ) {
89+ public boolean intersects (final Line other ) {
90+ final boolean thisIsVertical = start .x == end .x ;
15491 final boolean otherIsVertical = other .start .x == other .end .x ;
15592
156- if (!otherIsVertical ) {
93+ if (thisIsVertical && otherIsVertical || ! thisIsVertical && !otherIsVertical ) {
15794 return false ;
15895 }
15996
160- return Math .min (start .x , end .x ) < other .start .x
161- && other .start .x < Math .max (start .x , end .x )
162- && Math .min (other .start .y , other .end .y ) <= start .y
163- && start .y < Math .max (other .start .y , other .end .y );
164- }
165-
166- public boolean intersectsBottomLine (final Line other ) {
167- final boolean otherIsVertical = other .start .x == other .end .x ;
168-
169- if (!otherIsVertical ) {
170- return false ;
171- }
172-
173- return Math .min (start .x , end .x ) < other .start .x
174- && other .start .x < Math .max (start .x , end .x )
175- && Math .min (other .start .y , other .end .y ) < start .y
176- && start .y <= Math .max (other .start .y , other .end .y );
177- }
178-
179- public boolean intersectsLeftLine (final Line other ) {
180- final boolean otherIsVertical = other .start .x == other .end .x ;
181-
182- if (otherIsVertical ) {
183- return false ;
97+ if (thisIsVertical ) {
98+ return Math .min (other .start .x , other .end .x ) < start .x
99+ && start .x < Math .max (other .start .x , other .end .x )
100+ && Math .min (start .y , end .y ) <= other .start .y
101+ && other .start .y < Math .max (start .y , end .y );
184102 }
185103
186104 return Math .min (start .x , end .x ) <= other .start .x
187- && other .start .x < Math .max (start .x , end .x )
188- && Math .min (other .start .y , other .end .y ) < start .y
189- && start .y < Math .max (other .start .y , other .end .y );
190- }
191-
192- public boolean intersectsRightLine (final Line other ) {
193- final boolean otherIsVertical = other .start .x == other .end .x ;
194-
195- if (otherIsVertical ) {
196- return false ;
197- }
198-
199- return Math .min (start .x , end .x ) < other .start .x
200- && other .start .x <= Math .max (start .x , end .x )
201- && Math .min (other .start .y , other .end .y ) < start .y
202- && start .y < Math .max (other .start .y , other .end .y );
203- }
204-
205- public boolean intersectsRayBelow (final Line other ) {
206- final boolean otherIsVertical = other .start .x == other .end .x ;
207-
208- if (!otherIsVertical ) {
209- return false ;
210- }
211-
212- return Math .min (start .x , end .x ) < other .start .x
213105 && other .start .x <= Math .max (start .x , end .x )
214106 && Math .min (other .start .y , other .end .y ) <= start .y
215- && start .y < Math .max (other .start .y , other .end .y );
216- }
217-
218- public boolean intersectsRayAbove (final Line other ) {
219- final boolean otherIsVertical = other .start .x == other .end .x ;
220-
221- if (!otherIsVertical ) {
222- return false ;
223- }
224-
225- return Math .min (start .x , end .x ) < other .start .x
226- && other .start .x <= Math .max (start .x , end .x )
227- && Math .min (other .start .y , other .end .y ) < start .y
228107 && start .y <= Math .max (other .start .y , other .end .y );
229108 }
230109 }
0 commit comments