Skip to content

Commit 1f458d5

Browse files
committed
AoC 2025 Day 9 - java - cleanup
1 parent 506a48b commit 1f458d5

File tree

2 files changed

+60
-52
lines changed

2 files changed

+60
-52
lines changed

src/main/java/AoC2025_09.java

Lines changed: 39 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import com.github.pareronia.aoc.Grid.Cell;
22
import com.github.pareronia.aoc.IterTools;
3-
import com.github.pareronia.aoc.Pairwise;
4-
import com.github.pareronia.aoc.Pairwise.Pair;
53
import com.github.pareronia.aoc.StringOps;
64
import com.github.pareronia.aoc.StringOps.StringSplit;
75
import com.github.pareronia.aoc.Utils;
86
import com.github.pareronia.aoc.solution.Sample;
97
import com.github.pareronia.aoc.solution.Samples;
108
import com.github.pareronia.aoc.solution.SolutionBase;
119

12-
import java.util.ArrayList;
1310
import java.util.List;
11+
import java.util.stream.Stream;
1412

1513
@SuppressWarnings({"PMD.ClassNamingConventions", "PMD.NoPackage"})
1614
public final class AoC2025_09 extends SolutionBase<List<Cell>, Long, Long> {
@@ -42,57 +40,21 @@ protected List<Cell> parseInput(final List<String> inputs) {
4240

4341
@Override
4442
public Long solvePart1(final List<Cell> reds) {
45-
return Utils.stream(IterTools.combinations(reds.size(), 2))
46-
.mapToLong(
47-
c -> {
48-
final long dr =
49-
Math.abs(reds.get(c[0]).getRow() - reds.get(c[1]).getRow()) + 1;
50-
final long dc =
51-
Math.abs(reds.get(c[0]).getCol() - reds.get(c[1]).getCol()) + 1;
52-
return dr * dc;
53-
})
54-
.max()
55-
.getAsLong();
43+
return rectangles(reds).mapToLong(Rectangle::getArea).max().getAsLong();
5644
}
5745

5846
@Override
5947
public Long solvePart2(final List<Cell> reds) {
60-
final List<Pair<Cell>> borderSegments = new ArrayList<>();
61-
Pairwise.pairwise(reds.iterator()).forEachRemaining(borderSegments::add);
62-
borderSegments.add(Pair.of(reds.getLast(), reds.getFirst()));
63-
long ans = 0;
64-
for (int i = 0; i < reds.size(); i++) {
65-
for (int j = i + 1; j < reds.size(); j++) {
66-
final Cell celli = reds.get(i);
67-
final Cell cellj = reds.get(j);
68-
final int minRow = Math.min(celli.getRow(), cellj.getRow());
69-
final int maxRow = Math.max(celli.getRow(), cellj.getRow());
70-
final int minCol = Math.min(celli.getCol(), cellj.getCol());
71-
final int maxCol = Math.max(celli.getCol(), cellj.getCol());
72-
if (borderSegments.stream()
73-
.allMatch(
74-
pair ->
75-
Math.max(pair.first().getCol(), pair.second().getCol())
76-
<= minCol
77-
|| Math.min(
78-
pair.first().getCol(),
79-
pair.second().getCol())
80-
>= maxCol
81-
|| Math.max(
82-
pair.first().getRow(),
83-
pair.second().getRow())
84-
<= minRow
85-
|| Math.min(
86-
pair.first().getRow(),
87-
pair.second().getRow())
88-
>= maxRow)) {
89-
final long dc = maxCol - minCol + 1;
90-
final long dr = maxRow - minRow + 1;
91-
ans = Math.max(dc * dr, ans);
92-
}
93-
}
94-
}
95-
return ans;
48+
final List<Rectangle> borderSegments =
49+
IterTools.pairwise(Stream.concat(reds.stream(), Stream.of(reds.getFirst())))
50+
.stream()
51+
.map(pair -> Rectangle.from(pair.first(), pair.second()))
52+
.toList();
53+
return rectangles(reds)
54+
.filter(rect -> borderSegments.stream().noneMatch(rect::intersects))
55+
.mapToLong(Rectangle::getArea)
56+
.max()
57+
.getAsLong();
9658
}
9759

9860
@Samples({
@@ -114,4 +76,31 @@ public static void main(final String[] args) throws Exception {
11476
2,3
11577
7,3
11678
""";
79+
80+
record Rectangle(int minRow, int minCol, int maxRow, int maxCol) {
81+
82+
public static Rectangle from(final Cell first, final Cell second) {
83+
final int minRow = Math.min(first.getRow(), second.getRow());
84+
final int maxRow = Math.max(first.getRow(), second.getRow());
85+
final int minCol = Math.min(first.getCol(), second.getCol());
86+
final int maxCol = Math.max(first.getCol(), second.getCol());
87+
return new Rectangle(minRow, minCol, maxRow, maxCol);
88+
}
89+
90+
public boolean intersects(final Rectangle other) {
91+
return !(this.maxCol <= other.minCol
92+
|| this.minCol >= other.maxCol
93+
|| this.maxRow <= other.minRow
94+
|| this.minRow >= other.maxRow);
95+
}
96+
97+
public long getArea() {
98+
return (long) (maxRow - minRow + 1) * (maxCol - minCol + 1);
99+
}
100+
}
101+
102+
private Stream<Rectangle> rectangles(final List<Cell> reds) {
103+
return Utils.stream(IterTools.combinations(reds.size(), 2))
104+
.map(combo -> Rectangle.from(reds.get(combo[0]), reds.get(combo[1])));
105+
}
117106
}

src/main/java/com/github/pareronia/aoc/IterTools.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import static java.util.stream.Collectors.toList;
44

5+
import org.apache.commons.math3.util.CombinatoricsUtils;
6+
57
import java.util.ArrayList;
68
import java.util.Arrays;
79
import java.util.Iterator;
@@ -10,8 +12,6 @@
1012
import java.util.function.Consumer;
1113
import java.util.stream.Stream;
1214

13-
import org.apache.commons.math3.util.CombinatoricsUtils;
14-
1515
public class IterTools {
1616

1717
// TODO potentially huge storage cost -> make iterative version
@@ -20,6 +20,10 @@ public static <T> Stream<List<T>> permutations(final Iterable<T> iterable) {
2020
IterTools.permutations(iterable, builder::add);
2121
return builder.build();
2222
}
23+
24+
public static <T> IterToolsIterator<Pairwise.Pair<T>> pairwise(final Stream<T> stream) {
25+
return asIterToolsIterator(Pairwise.pairwise(stream.iterator()));
26+
}
2327

2428
@SuppressWarnings("unchecked")
2529
public static <T> void permutations(
@@ -262,4 +266,19 @@ default Iterable<T> iterable() {
262266
return () -> this;
263267
}
264268
}
269+
270+
private static <T> IterToolsIterator<T> asIterToolsIterator(final Iterator<T> iterator) {
271+
return new IterToolsIterator<>() {
272+
273+
@Override
274+
public boolean hasNext() {
275+
return iterator.hasNext();
276+
}
277+
278+
@Override
279+
public T next() {
280+
return iterator.next();
281+
}
282+
};
283+
}
265284
}

0 commit comments

Comments
 (0)