-
Notifications
You must be signed in to change notification settings - Fork 0
/
AoC2021_15.java
142 lines (122 loc) Β· 4.69 KB
/
AoC2021_15.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import static com.github.pareronia.aoc.Utils.toAString;
import static java.util.stream.Collectors.toSet;
import java.util.List;
import java.util.Set;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import com.github.pareronia.aoc.IntGrid;
import com.github.pareronia.aoc.Grid.Cell;
import com.github.pareronia.aoc.graph.AStar;
import com.github.pareronia.aocd.Aocd;
import com.github.pareronia.aocd.Puzzle;
public class AoC2021_15 extends AoCBase {
private static final Cell START = Cell.at(0,0);
private final IntGrid grid;
private AoC2021_15(final List<String> input, final boolean debug) {
super(debug);
this.grid = IntGrid.from(input);
}
public static final AoC2021_15 create(final List<String> input) {
return new AoC2021_15(input, false);
}
public static final AoC2021_15 createDebug(final List<String> input) {
return new AoC2021_15(input, true);
}
private int getRisk(final Cell cell) {
int value = this.grid.getValue(
Cell.at(cell.getRow() % this.grid.getHeight(),
cell.getCol() % this.grid.getWidth()))
+ cell.getRow() / this.grid.getHeight()
+ cell.getCol() / this.grid.getWidth();
while (value > 9) {
value -= 9;
}
return value;
}
private Stream<Cell> findNeighbours(final Cell c, final int tiles) {
return c.capitalNeighbours()
.filter(n -> n.getRow() >= 0)
.filter(n -> n.getCol() >= 0)
.filter(n -> n.getRow() < tiles * this.grid.getHeight())
.filter(n -> n.getCol() < tiles * this.grid.getWidth());
}
private AStar.Result<Cell> runAStar(final int tiles) {
final Cell end = Cell.at(
tiles * this.grid.getHeight() - 1,
tiles * this.grid.getWidth() - 1);
return AStar.execute(
START,
end::equals,
cell -> findNeighbours(cell, tiles),
this::getRisk);
}
private int solve(final int tiles) {
final Cell end = Cell.at(
tiles * this.grid.getHeight() - 1,
tiles * this.grid.getWidth() - 1);
return (int) runAStar(tiles).getDistance(end);
}
private void visualize(final int tiles) {
final Cell end = Cell.at(
tiles * this.grid.getHeight() - 1,
tiles * this.grid.getWidth() - 1);
final Set<Cell> path = runAStar(tiles).getPath(end).stream().collect(toSet());
IntStream.range(0, tiles * this.grid.getHeight()).forEach(row -> {
final String string = IntStream.range(0, tiles * this.grid.getWidth())
.mapToObj(col -> {
if (path.contains(Cell.at(row, col))) {
return '#';
} else {
return '.';
}
})
.collect(toAString());
System.out.println(string);
});
}
public void visualizePart1() {
visualize(1);
}
public void visualizePart2() {
visualize(5);
}
@Override
public Integer solvePart1() {
return solve(1);
}
@Override
public Integer solvePart2() {
return solve(5);
}
public static void main(final String[] args) throws Exception {
assert AoC2021_15.create(TEST).getRisk(Cell.at(1, 1)) == 3;
assert AoC2021_15.create(TEST).getRisk(Cell.at(1, 1)) == 3;
assert AoC2021_15.create(TEST).getRisk(Cell.at(11, 1)) == 4;
assert AoC2021_15.create(TEST).getRisk(Cell.at(1, 2)) == 8;
assert AoC2021_15.create(TEST).getRisk(Cell.at(1, 22)) == 1;
assert AoC2021_15.create(TEST).getRisk(Cell.at(1, 32)) == 2;
assert AoC2021_15.create(TEST).getRisk(Cell.at(11, 1)) == 4;
assert AoC2021_15.createDebug(TEST).solvePart1() == 40;
AoC2021_15.createDebug(TEST).visualizePart1();
assert AoC2021_15.createDebug(TEST).solvePart2() == 315;
AoC2021_15.createDebug(TEST).visualizePart2();
final Puzzle puzzle = Aocd.puzzle(2021, 15);
final List<String> input = puzzle.getInputData();
puzzle.check(
() -> lap("Part 1", create(input)::solvePart1),
() -> lap("Part 2", create(input)::solvePart2)
);
}
private static final List<String> TEST = splitLines(
"1163751742\r\n" +
"1381373672\r\n" +
"2136511328\r\n" +
"3694931569\r\n" +
"7463417111\r\n" +
"1319128137\r\n" +
"1359912421\r\n" +
"3125421639\r\n" +
"1293138521\r\n" +
"2311944581"
);
}