-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay12.java
85 lines (71 loc) · 2.3 KB
/
Day12.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import com.horstmann.adventofcode.*;
CharGrid grid;
List<Region> regions;
class Region { // Can't be a record because it needs the non-static grid from the enclosing scope
Set<Location> plots;
Region(Set<Location> plots) {
this.plots = plots;
}
long price() {
return plots.size() * perimeter();
}
long discountedPrice() {
return plots.size() * corners();
}
long perimeter() {
return plots.stream().mapToLong(p -> 4 - grid.sameNeighbors(p).size()).sum();
}
/* y
* ↖ ↑
* ┌──
* x ← │ p
*
* p has a 90° corner in ↖ direction if p ≠ and p ≠ y
*/
boolean hasExteriorCorner(Location p, Direction dd) {
var c = grid.get(p);
return c != grid.get(p.moved(dd.turn(-1))) && c != grid.get(p.moved(dd.turn(1)));
}
/* z y
* ↖│ ↑
* ──┘
* x ← p
*
* p has a 270° corner in ↖ direction if p = x, and p = y, p ≠ z
*/
boolean hasInteriorCorner(Location p, Direction dd) {
var c = grid.get(p);
return c == grid.get(p.moved(dd.turn(-1))) && c == grid.get(p.moved(dd.turn(1))) && c != grid.get(p.moved(dd));
}
int corners(Location loc) {
int sum = 0;
for (var dd : Direction.DIAGONALS) {
if (hasExteriorCorner(loc, dd)) sum++;
if (hasInteriorCorner(loc, dd)) sum++;
}
return sum;
}
int corners() {
return plots.stream().mapToInt(this::corners).sum();
}
}
void parse(Path path) throws IOException {
grid = CharGrid.parse(path);
regions = Graphs.connectedComponents(grid.locations().toList(), grid::sameNeighbors).stream().map(Region::new).toList();
}
Object part1() {
return regions.stream().mapToLong(Region::price).sum();
}
Object part2() {
return regions.stream().mapToLong(Region::discountedPrice).sum();
}
void main() throws IOException {
Util.time(() -> {
parse(Util.inputPath("a"));
IO.println(part1());
IO.println(part2());
parse(Util.inputPath("z"));
IO.println(part1());
IO.println(part2());
});
}