Skip to content

Commit eb0baa9

Browse files
committed
AOC 2025 day 9
1 parent 5c7b001 commit eb0baa9

4 files changed

Lines changed: 36 additions & 158 deletions

File tree

adventofcode/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,7 +1658,7 @@
16581658
[20242402tests]: src/test/java/org/ck/adventofcode/year2024/Day24Test.java
16591659
[20242501tests]: src/test/java/org/ck/adventofcode/year2024/Day25Test.java
16601660

1661-
# 2025 (16/24)
1661+
# 2025 (18/24)
16621662

16631663
| # | Name | Solution | Test |
16641664
|---------:|-------------------------------------------------|:------------------------------------:|:---------------------------------:|
@@ -1678,8 +1678,8 @@
16781678
| 20250702 | [Day 7: Laboratories - Part 2][20250702] | ✅[💾][20250702solution] | ✅[💾][20250702tests] |
16791679
| 20250801 | [Day 8: Playground][20250801] | ✅[💾][20250801solution] | ✅[💾][20250801tests] |
16801680
| 20250802 | [Day 8: Playground - Part 2][20250802] | ✅[💾][20250802solution] | ✅[💾][20250802tests] |
1681-
| 20250901 | [Day 9: ][20250901] | [💾][20250901solution] | [💾][20250901tests] |
1682-
| 20250902 | [Day 9: - Part 2][20250902] | [💾][20250902solution] | [💾][20250902tests] |
1681+
| 20250901 | [Day 9: Movie Theater][20250901] | ✅[💾][20250901solution] | ✅[💾][20250901tests] |
1682+
| 20250902 | [Day 9: Movie Theater - Part 2][20250902] | ✅[💾][20250902solution] | ✅[💾][20250902tests] |
16831683
| 20251001 | [Day 10: ][20251001] | [💾][20251001solution] | [💾][20251001tests] |
16841684
| 20251002 | [Day 10: - Part 2][20251002] | [💾][20251002solution] | [💾][20251002tests] |
16851685
| 20251101 | [Day 11: ][20251101] | [💾][20251101solution] | [💾][20251101tests] |

adventofcode/src/main/java/org/ck/adventofcode/year2025/Day09.java

Lines changed: 32 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@
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")
1917
public 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
}

adventofcode/src/test/java/org/ck/adventofcode/year2025/Day09Test.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package org.ck.adventofcode.year2025;
22

33
import org.ck.adventofcode.util.BaseAOCTest;
4-
import org.junit.jupiter.api.Disabled;
54
import org.junit.jupiter.params.ParameterizedTest;
65
import org.junit.jupiter.params.provider.ValueSource;
76

8-
@Disabled
97
class Day09Test extends BaseAOCTest {
108
@ParameterizedTest
119
@ValueSource(strings = {"01a"})
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1613305596

0 commit comments

Comments
 (0)