Skip to content

Commit e9cfd21

Browse files
committed
Add year 2022 day12
1 parent 656ab88 commit e9cfd21

File tree

6 files changed

+267
-12
lines changed

6 files changed

+267
-12
lines changed

benchmark-jmh/src/main/java/dev/linl33/adventofcode/jmh/JmhSolutionBenchmark.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public interface JmhSolutionBenchmark<T1, T2> extends AdventSolutionBenchmark<T1
1717
default void benchmark(BenchmarkOption... options) {
1818
options = Objects.requireNonNullElse(options, new JmhBenchmarkOption[] {
1919
JmhBenchmarkOption.PART_1,
20-
JmhBenchmarkOption.PART_2
20+
JmhBenchmarkOption.PART_2,
2121
});
2222

2323
var opt = Arrays
@@ -33,7 +33,7 @@ default void benchmark(BenchmarkOption... options) {
3333
(left, right) -> left
3434
)
3535
.param("solutionClass", getClass().getName())
36-
// .jvmArgsPrepend("-XX:+UseParallelGC")
36+
.jvmArgsPrepend("-XX:+UseParallelGC")
3737
// .warmupIterations(2)
3838
// .measurementIterations(2)
3939
.forks(1)

lib/src/main/java/dev/linl33/adventofcode/lib/graph/GraphUtil.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,23 +193,24 @@ private static <R> R aStarIntInternal(int start,
193193
// visitCounter++;
194194

195195
var current = minNode;
196+
var currentGScore = gScore[current];
196197
var neighbors = neighborsFunc.apply(current);
197198

198-
for (int neighbor : neighbors) {
199-
var tentativeGScore = gScore[current] + cost.applyAsInt(current, neighbor);
200-
if (tentativeGScore < gScore[neighbor]) {
199+
for (var neighbor : neighbors) {
200+
var neighborCost = cost.applyAsInt(current, neighbor);
201+
int tentativeGScore;
202+
if (neighborCost < gScore[neighbor] && (tentativeGScore = currentGScore + neighborCost) < gScore[neighbor]) {
201203
gScore[neighbor] = tentativeGScore;
202204

203-
openSetFScore[neighbor] = tentativeGScore + heuristic.applyAsInt(neighbor);
204-
openSetCounter++;
205-
206-
onNewEdge.accept(current, neighbor);
207-
208-
if (openSetFScore[neighbor] < minFScore || openSetCounter == 1) {
209-
minFScore = openSetFScore[neighbor];
205+
var neighborFScore = (openSetFScore[neighbor] = tentativeGScore + heuristic.applyAsInt(neighbor));
206+
if (openSetCounter == 0 || neighborFScore < minFScore) {
207+
minFScore = neighborFScore;
210208
minNode = neighbor;
211209
hasMin = true;
212210
}
211+
212+
openSetCounter++;
213+
onNewEdge.accept(current, neighbor);
213214
}
214215
}
215216
}
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
package dev.linl33.adventofcode.year2022;
2+
3+
import dev.linl33.adventofcode.lib.graph.GraphUtil;
4+
import dev.linl33.adventofcode.lib.grid.RowArrayGrid;
5+
import org.jetbrains.annotations.NotNull;
6+
7+
import java.io.BufferedReader;
8+
import java.util.Arrays;
9+
import java.util.function.IntBinaryOperator;
10+
import java.util.function.IntUnaryOperator;
11+
12+
public class Day12 extends AdventSolution2022<Integer, Integer> {
13+
private static final int POTENTIAL_ENDPOINTS_MAX = 100;
14+
15+
public static void main(String[] args) {
16+
new Day12().runAndPrintAll();
17+
}
18+
19+
@Override
20+
public Integer part1(@NotNull BufferedReader reader) throws Exception {
21+
return calculatePathLength(reader, false);
22+
}
23+
24+
@Override
25+
public Integer part2(@NotNull BufferedReader reader) throws Exception {
26+
return calculatePathLength(reader, true);
27+
}
28+
29+
private static int calculatePathLength(@NotNull BufferedReader reader, boolean fromEnd) {
30+
var grid = new RowArrayGrid(reader);
31+
var gridBackingArray = grid.array();
32+
33+
var start = 0;
34+
var end = 0;
35+
for (int i = 0; i < gridBackingArray.length; i++) {
36+
if (gridBackingArray[i] == 'E') {
37+
gridBackingArray[i] = 'z';
38+
end = i + 1;
39+
} else if (gridBackingArray[i] == 'S') {
40+
gridBackingArray[i] = 'a';
41+
start = i + 1;
42+
}
43+
}
44+
45+
var pathStart = fromEnd ? end : start;
46+
var pathEnd = fromEnd ? 0 : end;
47+
48+
IntUnaryOperator heuristic;
49+
var heuristicCache = new int[aStarGraphSize(grid.width(), grid.height())];
50+
if (!fromEnd) {
51+
var pathEndX = pathEnd % grid.width();
52+
var pathEndY = pathEnd / grid.width();
53+
54+
heuristic = p -> {
55+
if (heuristicCache[p] != 0) {
56+
return heuristicCache[p];
57+
}
58+
59+
p = p - 1;
60+
var x = p % grid.width();
61+
var y = p / grid.width();
62+
63+
return (heuristicCache[p + 1] = Math.abs(pathEndX - x) + Math.abs(pathEndY - y));
64+
};
65+
} else {
66+
var potentialEndpoints = new int[POTENTIAL_ENDPOINTS_MAX * 2];
67+
var potentialEndpointsCount = 0;
68+
69+
gridLoop:
70+
for (int i = 0; i < gridBackingArray.length; i++) {
71+
if (gridBackingArray[i] != 'a') {
72+
continue;
73+
}
74+
75+
var x = i % grid.width();
76+
var y = i / grid.width();
77+
78+
for (int deltaY = -1; deltaY <= 1; deltaY++) {
79+
for (int deltaX = -1; deltaX <= 1; deltaX++) {
80+
if ((deltaY == 0) == (deltaX == 0)) {
81+
continue;
82+
}
83+
84+
var x2 = x + deltaX;
85+
var y2 = y + deltaY;
86+
87+
if (!grid.isWithinBounds(x2, y2)) {
88+
continue;
89+
}
90+
91+
// the endpoint has to have a neighbor with elevation 'b'
92+
// if its lowest elevation is 'c' then it's inaccessible
93+
// if its highest elevation is 'a' then it has a neighbor with a shorter path
94+
if (grid.get(x2, y2) == 'b') {
95+
potentialEndpoints[potentialEndpointsCount++] = x;
96+
potentialEndpoints[potentialEndpointsCount++] = y;
97+
continue gridLoop;
98+
}
99+
}
100+
}
101+
}
102+
103+
var finalPotentialEndpointsCount = potentialEndpointsCount;
104+
heuristic = p -> {
105+
if (heuristicCache[p] != 0) {
106+
return heuristicCache[p];
107+
}
108+
109+
p = p - 1;
110+
var x = p % grid.width();
111+
var y = p / grid.width();
112+
113+
var min = Integer.MAX_VALUE;
114+
for (int i = 0; i < finalPotentialEndpointsCount; i += 2) {
115+
var pathEndX = potentialEndpoints[i];
116+
var pathEndY = potentialEndpoints[i + 1];
117+
118+
var manhattanDistance = Math.abs(pathEndX - x) + Math.abs(pathEndY - y);
119+
min = Math.min(min, manhattanDistance);
120+
}
121+
122+
return (heuristicCache[p + 1] = min);
123+
};
124+
}
125+
126+
var elevationDiff = (fromEnd ? (IntBinaryOperator) ((a, b) -> a - b) : (IntBinaryOperator) ((a, b) -> b - a));
127+
128+
var neighbors = new int[4];
129+
var finalStart = start;
130+
var pathLength = GraphUtil.aStarLengthOnly(
131+
pathStart,
132+
pathEnd,
133+
p -> {
134+
p = p - 1;
135+
var x = p % grid.width();
136+
var y = p / grid.width();
137+
var currVal = gridBackingArray[p];
138+
139+
Arrays.fill(neighbors, finalStart);
140+
var neighborPointer = 0;
141+
142+
for (int deltaY = -1; deltaY <= 1; deltaY++) {
143+
for (int deltaX = -1; deltaX <= 1; deltaX++) {
144+
if ((deltaY == 0) == (deltaX == 0)) {
145+
// skip diagonal moves
146+
continue;
147+
}
148+
149+
var x2 = x + deltaX;
150+
var y2 = y + deltaY;
151+
152+
if (!grid.isWithinBounds(x2, y2)) {
153+
continue;
154+
}
155+
156+
var p2 = y2 * grid.width() + x2;
157+
var neighborVal = gridBackingArray[p2];
158+
159+
if (elevationDiff.applyAsInt(currVal, neighborVal) < 2) {
160+
neighbors[neighborPointer++] = (fromEnd && neighborVal == 'a') ? pathEnd : (p2 + 1);
161+
}
162+
}
163+
}
164+
165+
return neighbors;
166+
},
167+
heuristic,
168+
(a, b) -> b == finalStart ? Integer.MAX_VALUE : 1,
169+
aStarGraphSize(grid.width(), grid.height())
170+
);
171+
172+
return pathLength.orElseThrow();
173+
}
174+
175+
private static int aStarGraphSize(int width, int height) {
176+
return width * height + 1;
177+
}
178+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
abcccccccccccaaaaacccccccaaaaaaccccccccccccccccccccccccccccccccaaaaaaaaaaaaaacccccccccccccccccccaaaaaacccccccacccccccccaaccaaccccccccccccccccccccccccccccccaaaaaa
2+
abcccccccccccaaaaaaacccccaaaaaaccccccccaaccccccccccaaaaccccccccaaaaaaaaaaaaaccccccccccccccccccccaaaaaaccccaaaacccccccccaaaaaaccccccccccccccccccccccccccccccccaaaa
3+
abccccccccccaaaaaaaacccccaaaaaccccccccaaaacccccccccaaaacccccccccccaaaaaaacccccccccccccccccccccccaaaaacccccaaaaaaccccccccaaaaacccccccccccaaaccccccccccccccccccaaaa
4+
abccccccccccaaaaaaaaccccccaaaaacccccccaaaacccccccccaaaacccccaaaccccaaaaaaccccccccccccccccccccccccaaaaacccccaaaaacccccccaaaaaacccccccccccaaaacccccccccccccccccaaaa
5+
abccccccccccaaaaaaccccccccaaaaacccccccaaaaccccccccccaaacccccaaaaccaaaaaaaacccccccccccccccccccccccaaaaaccccaaaaacccccccaaaaaaaaccccccccccaaaaccaaccccccccccccaaaaa
6+
abcccccccccccccaaaccccccccccccccccccccccccccccccccccccccccccaaaaccaaaaaaaaccccccccccccccccccccccccccccccccaccaaccccaaaaaaaaaaacccccccccccaaaaaaccccccccccccccaccc
7+
abcacccccccccccccaaaccccccccccccccaaacccccccccccccccccccccccaaaccaaaacccaaacccccccccccccccccccccccaacccccccccccccccaaacccaaccccccccccccccaaaalllllccccccccccccccc
8+
abaacccccccccccccaaaaaacccccccccccaaaccccccccccccccccccccccccccccaaaccccaaaccccccccccccccccccccccaaccccccccccccccccaaaaaaaaccccccccccccccckklllllllccccaaaccccccc
9+
abaaaaacccccccccaaaaaaacccccccccaaaaaaaacccccaacccccccccccccccccccccccccaaaccccccccaacccccccccaaaaacaacaacaacccccaaaaaaaaccccccccccccaaakkkkllllllllcccaaaccccccc
10+
abaaaaaccccccccaaaaaaaacccccccccaaaaaaaacccccaaaaaacccccccccccccccccccccaaaccccccaaaacacccccccaaaaaaaacaaaaaccccaaaaaaaaaccccccccckkkkkkkkkklsssslllcccaaaaaacccc
11+
abaaaccccccccccaaaaaaacccccccccccaaaaacccccccaaaaaaccccccccccccccccccaaaaaaaaccccaaaaaacccccccccaaaaacaaaaacccccaaaaaaaacccaaaccjjkkkkkkkkkssssssslllcccaaaaacccc
12+
abaaaccccccccccccaaaaaacccccaacccaaaaaaccccaaaaaaaccaaaccccccccccccccaaaaaaaacccccaaaacccccccccaaaaaccaaaaaacccccccaaaaaaccaaaajjjjkkkkkkssssssssslllcddaaaaccccc
13+
abcaaacccccccccccaaaaaacaaacaacccaaaaaaccccaaaaaaaaaaaaaaccccccccccccccaaaaaccccccaaaaccccaaaaaaacaaacccaaaaaaacccaaaaaaaccaaajjjjrrrrrrssssuuuussqmmddddaaaccccc
14+
abccaacccccccccccaaccccccaaaaacccaaaccaccccaaaaaaaaaaaaaacccccccccccccaaaaaacccccaacaaccccaaaaacccaaccccacccaaaaaaaaaccaaccaaajjjrrrrrrrrssuuuuuvqqmmmdddaaaccccc
15+
abccccccccaaccccccccccccccaaaaaacccccccccccccaaaaaaaaaaaccccccccccccccaaaaaacccccccccccccaaaaaaccccccccccccaaaaaaaaaacccccccccjjjrrruuuuuuuuuuuvvqqmmmmddddaccccc
16+
abaacccccaaaaccccccccccccaaaaaaacccccccccccccaacccccaaaaacccccccccccccaccaaacccccccccccccaaaaaacccccccccccaaaaaaaaccccccccccccjjjrrruuuuuuuuxyyvvqqqmmmddddcccccc
17+
abaacccccaaaacccccccccccaaaaaaccccccccaaccccccccacccaaaaacccccccccccccccccccccccccccccccccaaaaacccccccccccaaaaaaacccccccccccccjjjrrttuxxxxuxxyyvvqqqqmmmmddddcccc
18+
abaacccccaaaacccccccccccaacaaacccccaaaaacccaaaaaaaccccccccccccccccccccccccccccccccccccccccaaacccccccccccccccaaaaaaccccccccccccjjjrrtttxxxxxxyyyvvqqqqqmmmmdddcccc
19+
abacccccccccccccccccccccccccaaccccccaaaaaccaaaaaaaccccccccaaccccccccccccccccccccccccccccccccccccccccccccccccaaaaaaccccccccccccjjjqrrttxxxxxxyyyvvvvqqqqmmmdddcccc
20+
abccccccccccccccccccccccccccccccccccaaaaaccaaaaaaacccccccaaaccccccccccaaaccccccccccccccccccaaaccccccccccccccaaccccccccccaaccccjjjqqqtttxxxxxyyyyyvvvqqqqmmmeeeccc
21+
SbaaccccccaccaaacccccccccccccccccccaaaaacccaaaaaaaaccccaaaaaaaacccccccaaacaaccccccccccccccaaaaaaccccccccccccccccccccccaaaaaaccciiiqqqttxxxxEzyyyyyvvvqqqnnneeeccc
22+
abaaccccccaaaaaaccccccccccccccccccccccaaccaaaaaaaaaacccaaaaaaaacccccaaaaaaaaccccccccccccccaaaaaaccccccccccccccccccccccaaaaaaccciiiqqtttxxxyyyyyyyvvvvqqqnnneeeccc
23+
abaaaaacccaaaaaaccccccccccccccccccccccccccaaaaaaaaaaccccaaaaaaccccccaaaaaaaaccccccccccccccaaaaaacccccccccccccccccccccccaaaaacciiiqqqttxxyyyyyyywvvvvrrrqnnneeeccc
24+
abaaaaacccaaaaaaaccccccccaaaccccccccccccccaacaaaccccccccaaaaaaccccccaaaaaaaccccccccccccccccaaaaaccccccccccccccccccccccaaaaaccciiiqqtttxxxyyyyywwwvrrrrrnnneeecccc
25+
abaaaccccaaaaaaaaccccccccaaaacccccccccccccccccaaccccccccaaaaaaccccccccaaaaaccccccccccccccccaacaaccccccccccccccccccccccaaaaaccciiqqqttxxxwwwwyyywwrrrrnnnnneeecccc
26+
abaaaccccaaaaaaaaccccccccaaaacccccaaaaacccccccaaccccccccaaccaacccccccaaacaaacccccccccccccccccccccccccccccccccccccccccccccccccciiqqqtttwwwwwwywwwrrrrnnnnneeeccccc
27+
abcaaaccccccaaaccccccccccaaaccccccaaaaacccccccccccccaaaaccccccccccccccaacccccccccccccccccccccccccccccccaaaacccccccccccccccccciiiqqqtttssssswwwwwrrrnnnneeeecccccc
28+
abccaaccccccaaaccccccccccccccccccaaaaaacccccccccccccaaaaccccccccccccccccccccccccccccccccccccccccccccccaaaaacccccccccccccccccciiiqqqqtssssssswwwwrronnnfeeeacccccc
29+
abcccccccccccccccccccccccccccccccaaaaaacccccccccccccaaaaccccccccccccccccccccccccccccccccccccccccccccccaaaaaaccccccccccccccccciiiiqqppssssssswwwwrroonfffeaacccccc
30+
abcccccccccccccccccccccccccccccccaaaaaacaaaccccccccccaacccccccccccccccccccccccccccccccccaaacccccccccccaaaaaaccccccccccccccccccihhpppppppppsssssrrroonfffaaaaacccc
31+
abcccccccccccccccccccccccccccccccccaacccaaaaacccccccccccccccccccccccccccccccccccccccccccaaaaaaccccccccaaaaaccccccccccccccccccchhhhppppppppppssssrooofffaaaaaacccc
32+
abccccccccaaaccccccccccccccccccccccccccaaaaacccccccccccccccccccccccccccccccccccccaccccaaaaaaaaccccccccccaaacccccccccccccccccccchhhhhhhhhpppposssoooofffaaaaaccccc
33+
abccccccccaaaacccccaaccccccccccccccccccaaaaaccccccccccccccccccccccccaaccccccccccaaccccaaaaaaaacccccccccccccccccccccccccccccccccchhhhhhhhhgppooooooofffaaaaacccccc
34+
abaaccccccaaaacccccaacaaccccccccccccccccaaaaacccccccccccccccaacaaccaaaaaaccccaaaaacaacaaaaaaacccccccccccccccccccccccccccccccccccccchhhhhhgggooooooffffaaaaaaccccc
35+
abaaacccccaaaacccccaaaaaccccccccccccccccaaccccccccccccccccccaaaaaccaaaaaaccccaaaaaaaacccaaaaaccccccccccccccccccccccccaaacaacccccccccccccgggggooooffffccccaacccccc
36+
abaaaccccccccccccaaaaaaccccaaccccccccccccccccccaaacccccccccccaaaaaaaaaaaacaacccaaaaaccccaacaaacccccccccccccccccccccccaaaaaaccccccccccccccaggggggggfffcccccccccccc
37+
abaaaccccccccccccaaaaaaaacaaaaccccccccaaaccccccaaaacccccccccaaaaaaaaaaaaaaaaccaaaaacccccaaaaaccccccccccccccaaccccccccaaaaaaccccccccccccccaagggggggfccccccccccccca
38+
abaacccccccccccccaccaaaaacaaaaccccccccaaaccccccaaaacccccccccaaaaccaaaaaaaaaaccaacaaaccccccaaaccccccccccccaaaaaacccccaaaaaaacccccccccccccaaaaccggggcccccccccccccaa
39+
abaacccccccccccccccaaacaccaaaacccccaaaaaaaaccccaaaccccccccccccaaccaaaaaaaacccccccaacccccaacaaaaacccccccccaaaaaacccccaaaaaaaaccccccccccccaaaccccccccccccccccaaacaa
40+
abcccccccccccccccccaaccccccccccccccaaaaaaaaccccccccccccccccccccaaaaaaaaaaaccccccccccccccaaaaaaaacccccccccaaaaaacccccaaaaaaaaccccccccccccacaccccccccccccccccaaaaaa
41+
abccccccccccccccccccccccccccccccccccaaaaaacccccccccccccccccccccaaaaaaaaaaaaccccccccccccccaaaaaaccccccccccaaaaaccccccccaaacccccccccccccccccccccccccccccccccccaaaaa
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Sabqponm
2+
abcryxxl
3+
accszExk
4+
acctuvwj
5+
abdefghi
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package dev.linl33.adventofcode.year2022.test;
2+
3+
import dev.linl33.adventofcode.lib.solution.AdventSolution;
4+
import dev.linl33.adventofcode.testlib.AdventSolutionTest;
5+
import dev.linl33.adventofcode.year2022.Day12;
6+
7+
import java.util.Map;
8+
9+
public class Day12Test implements AdventSolutionTest<Integer, Integer> {
10+
@Override
11+
public AdventSolution<Integer, Integer> newSolutionInstance() {
12+
return new Day12();
13+
}
14+
15+
@Override
16+
public Map<Object, Integer> getPart1Cases() {
17+
return Map.of(
18+
"day12", 481,
19+
"day12test1", 31
20+
);
21+
}
22+
23+
@Override
24+
public Map<Object, Integer> getPart2Cases() {
25+
return Map.of(
26+
"day12", 480,
27+
"day12test1", 29
28+
);
29+
}
30+
}

0 commit comments

Comments
 (0)