diff --git a/adventofcode/src/main/java/org/ck/adventofcode/year2024/Day18.java b/adventofcode/src/main/java/org/ck/adventofcode/year2024/Day18.java index bbc583ef..0154dd8c 100644 --- a/adventofcode/src/main/java/org/ck/adventofcode/year2024/Day18.java +++ b/adventofcode/src/main/java/org/ck/adventofcode/year2024/Day18.java @@ -16,11 +16,6 @@ name = "Day 18: RAM Run - Part 2", url = "https://adventofcode.com/2024/day/18#part2", category = "2024") -/// possible optimisations for part 2: -///
-///     - do a binary search on the remaining data packets
-///     - only calculate next path if the new corrupted packed is on the last optimal path
-/// 
public class Day18 extends AOCSolution { @Override @@ -47,6 +42,7 @@ private void run( } final Set corrupted = packets.stream().limit(offset).collect(Collectors.toSet()); + final Set previousPath = new HashSet<>(); boolean foundPath = initialFoundPath; @@ -54,7 +50,14 @@ private void run( foundPath = false; corrupted.add(packets.get(offset)); - final Set visited = new HashSet<>(); + if (!previousPath.isEmpty() && !previousPath.contains(packets.get(offset))) { + foundPath = true; + ++offset; + continue; + } + + final Map origins = new HashMap<>(); + origins.put(new Coordinate(0, 0), null); final Queue queue = new PriorityQueue<>(Comparator.comparingInt(State::count)); queue.add(new State(new Coordinate(0, 0), 0)); @@ -71,24 +74,27 @@ private void run( break; } - if (!visited.contains(coordinate)) { - visited.add(coordinate); - - for (final Coordinate next : - Set.of( - new Coordinate(coordinate.x() + 1, coordinate.y()), - new Coordinate(coordinate.x(), coordinate.y() + 1), - new Coordinate(coordinate.x() - 1, coordinate.y()), - new Coordinate(coordinate.x(), coordinate.y() - 1))) { - if (next.x() >= 0 && next.y() >= 0 && next.x() <= gridSize && next.y() <= gridSize) { - if (!visited.contains(next) && !corrupted.contains(next)) { - queue.add(new State(next, current.count() + 1)); - } + for (final Coordinate next : + Set.of( + new Coordinate(coordinate.x() + 1, coordinate.y()), + new Coordinate(coordinate.x(), coordinate.y() + 1), + new Coordinate(coordinate.x() - 1, coordinate.y()), + new Coordinate(coordinate.x(), coordinate.y() - 1))) { + if (next.x() >= 0 && next.y() >= 0 && next.x() <= gridSize && next.y() <= gridSize) { + if (!origins.containsKey(next) && !corrupted.contains(next)) { + origins.put(next, coordinate); + queue.add(new State(next, current.count() + 1)); } } } } + Coordinate current = new Coordinate(gridSize, gridSize); + while (current != null) { + previousPath.add(current); + current = origins.get(current); + } + if (!foundPath && initialFoundPath) { final Coordinate last = packets.get(offset); print("%d,%d".formatted(last.x(), last.y()));