Skip to content

Commit 2a66da4

Browse files
committed
Year 2024 Day 20 Part 1
- NOk 5 test work with 1 robot
1 parent 4e22189 commit 2a66da4

File tree

1 file changed

+136
-22
lines changed
  • solutions/src/main/java/dev/vinyard/adventofcode/soluce/year2024/day21

1 file changed

+136
-22
lines changed

solutions/src/main/java/dev/vinyard/adventofcode/soluce/year2024/day21/ASD.java

Lines changed: 136 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import lombok.Setter;
55
import org.jgrapht.Graph;
66
import org.jgrapht.alg.interfaces.ShortestPathAlgorithm;
7-
import org.jgrapht.alg.shortestpath.AStarShortestPath;
7+
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
88
import org.jgrapht.graph.DefaultWeightedEdge;
99
import org.jgrapht.graph.builder.GraphTypeBuilder;
1010

@@ -26,12 +26,8 @@ public Root(List<Code> codes) {
2626
}
2727

2828
private RequestHandler getRequestHandler() {
29-
Robot robotDegrees = new Robot();
30-
Robot robotRadiation = new Robot();
3129
Digicode digicodeDepressurized = new Digicode();
32-
33-
robotDegrees.setNext(robotRadiation);
34-
robotRadiation.setNext(digicodeDepressurized);
30+
Robot robot1 = new Robot(digicodeDepressurized);
3531

3632
return digicodeDepressurized;
3733
}
@@ -90,7 +86,7 @@ public static abstract class AbstractKeypad extends RequestHandler {
9086

9187
private final String[][] keypad;
9288

93-
private final Map<String, Point> buttons;
89+
protected final Map<String, Point> buttons;
9490

9591
private final Rectangle bounds;
9692

@@ -99,20 +95,20 @@ public static abstract class AbstractKeypad extends RequestHandler {
9995

10096
private final Point position;
10197

102-
private AbstractKeypad previous;
98+
protected AbstractKeypad previous;
10399

104100
public AbstractKeypad(String[][] keypad, AbstractKeypad previous) {
105-
this(keypad);
106-
this.previous = previous;
107-
}
108-
109-
public AbstractKeypad(String[][] keypad) {
110101
this.keypad = keypad;
102+
this.previous = previous;
111103
this.buttons = buildButtons();
112104
this.position = new Point(buttons.get("A"));
113105
this.bounds = new Rectangle(keypad[0].length, keypad.length);
114106
this.graph = buildGraph();
115-
this.shortestPathAlgorithm = new AStarShortestPath<>(graph, (b1, b2) -> buttons.get(b1.key).distance(buttons.get(b2.key)));
107+
this.shortestPathAlgorithm = new DijkstraShortestPath<>(graph);
108+
}
109+
110+
public AbstractKeypad(String[][] keypad) {
111+
this(keypad, null);
116112
}
117113

118114
private String getKeyAt(Point position) {
@@ -130,7 +126,7 @@ private Map<String, Point> buildButtons() {
130126
return buttons;
131127
}
132128

133-
private Map<Direction, String> getNeighbours(Point position) {
129+
protected Map<Direction, String> getNeighbours(Point position) {
134130
return Arrays.stream(Direction.values())
135131
.filter(d -> {
136132
Point p = d.move(position);
@@ -139,7 +135,7 @@ private Map<Direction, String> getNeighbours(Point position) {
139135
.collect(Collectors.toMap(Function.identity(), d -> getKeyAt(d.move(position))));
140136
}
141137

142-
private Graph<DepthVertex, KeyEdge> createEmptyGraph() {
138+
protected Graph<DepthVertex, KeyEdge> createEmptyGraph() {
143139
return GraphTypeBuilder.<DepthVertex, KeyEdge>directed()
144140
.allowingMultipleEdges(false)
145141
.allowingSelfLoops(false)
@@ -148,7 +144,7 @@ private Graph<DepthVertex, KeyEdge> createEmptyGraph() {
148144
.buildGraph();
149145
}
150146

151-
private Graph<DepthVertex, KeyEdge> buildGraph() {
147+
protected Graph<DepthVertex, KeyEdge> buildGraph() {
152148
Graph<DepthVertex, KeyEdge> graph = Optional.ofNullable(previous).map(p -> p.graph).orElse(createEmptyGraph());
153149

154150
int pressedLayer = graph.vertexSet().stream().mapToInt(DepthVertex::depth).max().orElse(-1) + 1;
@@ -157,12 +153,24 @@ private Graph<DepthVertex, KeyEdge> buildGraph() {
157153
// Layer 0 : The pressed button
158154
buttons.keySet().stream().map(k -> new DepthVertex(k, pressedLayer)).forEach(graph::addVertex);
159155

160-
// Last layer of the previous graph are all connected to the "A" pressed layer
161-
graph.vertexSet().stream().filter(v -> Objects.equals(v.depth(), pressedLayer - 1)).forEach(v -> graph.addEdge(v, new DepthVertex("A", pressedLayer), new KeyEdge()));
162-
163156
// Layer 1 : The released button (position of the arm)
164157
buttons.keySet().stream().map(k -> new DepthVertex(k, releasedLayer)).forEach(graph::addVertex);
165158

159+
// Before adding the edges between the pressed and released buttons, we need to replace all the edges from the previous graph
160+
List<KeyEdge> edges = graph.edgeSet().stream().filter(e -> Objects.nonNull(e.getKey())).toList();
161+
162+
edges.forEach(e -> {
163+
if (Objects.equals(e.getKey(), "A")) {
164+
graph.addEdge(new DepthVertex("A", pressedLayer), graph.getEdgeTarget(e), new KeyEdge("A", 1));
165+
} else {
166+
graph.addEdge(new DepthVertex(e.getKey(), pressedLayer), graph.getEdgeTarget(e));
167+
}
168+
graph.removeEdge(e);
169+
});
170+
171+
// Last layer of the previous graph are all connected to the "A" pressed layer
172+
graph.vertexSet().stream().filter(v -> Objects.equals(v.depth(), pressedLayer - 1)).forEach(v -> graph.addEdge(v, new DepthVertex("A", pressedLayer), new KeyEdge()));
173+
166174
// Add the edges between the pressed and released buttons
167175
// Going from pressed to released cost 0
168176
buttons.keySet().forEach(n -> graph.addEdge(new DepthVertex(n, pressedLayer), new DepthVertex(n, releasedLayer), new KeyEdge()));
@@ -209,6 +217,38 @@ public Digicode() {
209217
{null, "0", "A"}
210218
});
211219
}
220+
221+
protected Graph<DepthVertex, KeyEdge> buildGraph() {
222+
Graph<DepthVertex, KeyEdge> graph = createEmptyGraph();
223+
224+
int pressedLayer = 0;
225+
int releasedLayer = 1;
226+
227+
// Layer 0 : The pressed button
228+
buttons.keySet().stream().map(k -> new DepthVertex(k, pressedLayer)).forEach(graph::addVertex);
229+
230+
// Layer 1 : The released button (position of the arm)
231+
buttons.keySet().stream().map(k -> new DepthVertex(k, releasedLayer)).forEach(graph::addVertex);
232+
233+
// Add the edges between the pressed and released buttons
234+
// Going from pressed to released cost 0
235+
buttons.keySet().forEach(n -> graph.addEdge(new DepthVertex(n, pressedLayer), new DepthVertex(n, releasedLayer), new KeyEdge()));
236+
// Going from released to pressed cost 1 (A)
237+
buttons.keySet().forEach(n -> graph.addEdge(new DepthVertex(n, releasedLayer), new DepthVertex(n, pressedLayer), new KeyEdge("A", 1)));
238+
239+
// Add the edges between the released buttons
240+
buttons.forEach((key, position) ->
241+
getNeighbours(position).forEach((direction, neighbourKey) ->
242+
graph.addEdge(
243+
new DepthVertex(key, releasedLayer),
244+
new DepthVertex(neighbourKey, releasedLayer),
245+
new KeyEdge(direction.symbol, releasedLayer))
246+
)
247+
);
248+
249+
return graph;
250+
}
251+
212252
}
213253

214254
public static class Robot extends AbstractKeypad {
@@ -219,12 +259,86 @@ public Robot() {
219259
{"<", "v", ">"},
220260
});
221261
}
262+
263+
public Robot(AbstractKeypad previous) {
264+
super(new String[][]{
265+
{null, "^", "A"},
266+
{"<", "v", ">"},
267+
}, previous);
268+
}
269+
270+
protected Graph<DepthVertex, KeyEdge> buildGraph() {
271+
Graph<DepthVertex, KeyEdge> graph = Optional.ofNullable(previous).map(p -> p.graph).orElse(createEmptyGraph());
272+
273+
int precedingLayer = graph.vertexSet().stream().mapToInt(DepthVertex::depth).max().orElseThrow(); // 1
274+
//int pressedLayer = precedingLayer + 1; // 2
275+
int currentLayer = precedingLayer + 1; // 3
276+
277+
// Before adding the edges between the pressed and released buttons, we need to replace all the edges from the previous graph
278+
List<KeyEdge> edges = graph.edgeSet().stream().toList();
279+
280+
edges.stream().filter(e -> Objects.nonNull(e.getKey())).forEach(e -> { // Edge <
281+
DepthVertex source = graph.getEdgeSource(e); // source A
282+
DepthVertex target = graph.getEdgeTarget(e); // target 0
283+
284+
{
285+
// < A
286+
graph.addVertex(new DepthVertex(e.getKey(), currentLayer, source.key()));
287+
// graph.addVertex(new DepthVertex(e.getKey(), pressedLayer, source.key()));
288+
// graph.addEdge(new DepthVertex(e.getKey(), currentLayer, source.key()), new DepthVertex(e.getKey(), pressedLayer, source.key()), new KeyEdge("A", 1));
289+
290+
// < 0
291+
graph.addVertex(new DepthVertex(e.getKey(), currentLayer, target.key()));
292+
// graph.addVertex(new DepthVertex(e.getKey(), pressedLayer, target.key()));
293+
// graph.addEdge(new DepthVertex(e.getKey(), currentLayer, target.key()), new DepthVertex(e.getKey(), pressedLayer, target.key()), new KeyEdge("A", 1));
294+
295+
// A <
296+
graph.addVertex(new DepthVertex(source.key(), source.depth(), e.getKey()));
297+
298+
// 0 <
299+
graph.addVertex(new DepthVertex(target.key(), target.depth(), e.getKey()));
300+
301+
// < A pressed 0 <
302+
if (Objects.equals(source.depth(), target.depth())) {
303+
graph.addEdge(new DepthVertex(e.getKey(), currentLayer, source.key()), new DepthVertex(e.getKey(), currentLayer, target.key()), new KeyEdge("A", 1));
304+
} else {
305+
graph.addEdge(new DepthVertex(e.getKey(), currentLayer, source.key()), new DepthVertex(target.key(), target.depth()), new KeyEdge("A", 1));
306+
}
307+
}
308+
309+
graph.removeEdge(e);
310+
});
311+
312+
313+
graph.vertexSet().stream().filter(v -> Objects.equals(v.depth(), currentLayer))
314+
// .filter(v -> buttons.containsKey(v.key()))
315+
.forEach(v -> {
316+
getNeighbours(buttons.get(v.key())).forEach((direction, neighbourKey) -> {
317+
graph.addEdge(v, new DepthVertex(neighbourKey, currentLayer, v.origin()), new KeyEdge(direction.symbol, currentLayer));
318+
});
319+
320+
});
321+
322+
edges.stream().filter(e -> Objects.isNull(e.getKey())).forEach(e -> {
323+
DepthVertex source = graph.getEdgeSource(e); // source A
324+
DepthVertex target = graph.getEdgeTarget(e); // target 0
325+
// Last layer of the previous graph are all connected to the "A" pressed layer
326+
graph.addEdge(source, new DepthVertex("A", currentLayer, source.key()), new KeyEdge());
327+
graph.removeEdge(e);
328+
});
329+
330+
return graph;
331+
}
222332
}
223333

224-
public record DepthVertex(String key, int depth) {
334+
public record DepthVertex(String key, int depth, String origin) {
225335

226336
public DepthVertex(String key) {
227-
this(key, 0);
337+
this(key, 0, null);
338+
}
339+
340+
public DepthVertex(String key, int depth) {
341+
this(key, depth, null);
228342
}
229343

230344
}

0 commit comments

Comments
 (0)