Skip to content

Commit

Permalink
aoc 2016 day 24
Browse files Browse the repository at this point in the history
  • Loading branch information
TheCK committed Dec 10, 2024
1 parent 9df6b20 commit 4eee944
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 183 deletions.
14 changes: 7 additions & 7 deletions adventofcode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@
[20152402tests]: src/test/java/org/ck/adventofcode/year2015/Day24Test.java
[20152501tests]: src/test/java/org/ck/adventofcode/year2015/Day25Test.java

# 2016 (47/49)
# 2016 (49/49)

| # | Name | Solution | Test |
|---------:|---------------------------------------------------------------------|:------------------------------------:|:---------------------------------:|
Expand Down Expand Up @@ -252,8 +252,8 @@
| 20162202 | [Day 22: Grid Computing - Part 2][20162202] | ✅[💾][20162202solution] | ✅[💾][20162202tests] |
| 20162301 | [Day 23: Safe Cracking][20162301] | ✅[💾][20162301solution] | ✅[💾][20162301tests] |
| 20162302 | [Day 23: Safe Cracking - Part 2][20162302] | ✅[💾][20162302solution] | ✅[💾][20162302tests] |
| 20162401 | [Day 24: Air Duct Spelunking][20162401] | [💾][20162401solution] | [💾][20162401tests] |
| 20162402 | [Day 24: Air Duct Spelunking - Part 2][20162402] | [💾][20162402solution] | [💾][20162402tests] |
| 20162401 | [Day 24: Air Duct Spelunking][20162401] | ✅[💾][20162401solution] | ✅[💾][20162401tests] |
| 20162402 | [Day 24: Air Duct Spelunking - Part 2][20162402] | ✅[💾][20162402solution] | ✅[💾][20162402tests] |
| 20162501 | [Day 25: Clock Signal][20162501] | ✅[💾][20162501solution] | ✅[💾][20162501tests] |

[20160101]: https://adventofcode.com/2016/day/1
Expand Down Expand Up @@ -352,8 +352,8 @@
[20162202solution]: src/main/java/org/ck/adventofcode/year2016/Day22.java
[20162301solution]: src/main/java/org/ck/adventofcode/year2016/Day23.java
[20162302solution]: src/main/java/org/ck/adventofcode/year2016/Day23.java
[20162401solution]: src/main/java/org/ck/adventofcode/year2016/day24/Part1.java
[20162402solution]: src/main/java/org/ck/adventofcode/year2016/day24/Part2.java
[20162401solution]: src/main/java/org/ck/adventofcode/year2016/Day24.java
[20162402solution]: src/main/java/org/ck/adventofcode/year2016/Day24.java
[20162501solution]: src/main/java/org/ck/adventofcode/year2016/day25/Part1.java

[20160101tests]: src/test/java/org/ck/adventofcode/year2016/Day01Test.java
Expand Down Expand Up @@ -402,8 +402,8 @@
[20162202tests]: src/test/java/org/ck/adventofcode/year2016/Day22Test.java
[20162301tests]: src/test/java/org/ck/adventofcode/year2016/Day23Test.java
[20162302tests]: src/test/java/org/ck/adventofcode/year2016/Day23Test.java
[20162401tests]: src/test/java/org/ck/adventofcode/year2016/day24/Part1Test.java
[20162402tests]: src/test/java/org/ck/adventofcode/year2016/day24/Part2Test.java
[20162401tests]: src/test/java/org/ck/adventofcode/year2016/Day24Test.java
[20162402tests]: src/test/java/org/ck/adventofcode/year2016/Day24Test.java
[20162501tests]: src/test/java/org/ck/adventofcode/year2016/day25/Part1Test.java

# 2017 (15/16)
Expand Down
130 changes: 127 additions & 3 deletions adventofcode/src/main/java/org/ck/adventofcode/year2016/Day24.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,142 @@
package org.ck.adventofcode.year2016;

import java.util.*;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import org.ck.adventofcode.util.AOCSolution;
import org.ck.codechallengelib.annotation.Solution;

@Solution(
id = 20162401,
name = "Day 24: Air Duct Spelunking",
url = "https://adventofcode.com/2016/day/24",
category = "2016")
@Solution(
id = 20162402,
name = "Day 24: Air Duct Spelunking - Part 2",
url = "https://adventofcode.com/2016/day/24",
category = "2016")
public class Day24 extends AOCSolution {
@Override
protected void runPartOne(final Scanner in) {
run(in);
run(in, (lastStep, distances) -> 0);
}

@Override
protected void runPartTwo(final Scanner in) {
run(in);
run(in, (lastStep, distances) -> distances.get('0').get(lastStep));
}

private void run(final Scanner in) {}
private void run(
final Scanner in,
final BiFunction<Character, Map<Character, Map<Character, Integer>>, Integer>
lastStepLength) {
final List<char[]> grid = new ArrayList<>();

while (in.hasNextLine()) {
grid.add(in.nextLine().toCharArray());
}

final List<Target> wanted = new ArrayList<>();
for (int y = 0; y < grid.size(); ++y) {
for (int x = 0; x < grid.get(y).length; ++x) {
final char field = grid.get(y)[x];

if (field != '.' && field != '#') {
wanted.add(new Target(field, new Coordinate(x, y)));
}
}
}

final Map<Character, Map<Character, Integer>> distances = new HashMap<>();
for (int i = 0; i < wanted.size(); ++i) {
for (int j = i + 1; j < wanted.size(); ++j) {
final int steps =
findPathLength(grid, wanted.get(i).coordinate(), wanted.get(j).coordinate());

distances
.computeIfAbsent(wanted.get(i).name(), k -> new HashMap<>())
.computeIfAbsent(wanted.get(j).name(), k -> steps);
distances
.computeIfAbsent(wanted.get(j).name(), k -> new HashMap<>())
.computeIfAbsent(wanted.get(i).name(), k -> steps);
}
}

print(
getOverallDistance(
wanted.stream()
.map(Target::name)
.filter(target -> target != '0')
.collect(Collectors.toSet()),
distances,
'0',
lastStepLength));
}

private int getOverallDistance(
final Set<Character> remaining,
final Map<Character, Map<Character, Integer>> distances,
final char current,
final BiFunction<Character, Map<Character, Map<Character, Integer>>, Integer>
lastStepLength) {
if (remaining.isEmpty()) {
return lastStepLength.apply(current, distances);
}

int distance = Integer.MAX_VALUE;

for (final char next : remaining) {
distance =
Math.min(
distance,
getOverallDistance(
remaining.stream()
.filter(target -> target != next)
.collect(Collectors.toSet()),
distances,
next,
lastStepLength)
+ distances.get(current).get(next));
}

return distance;
}

private static int findPathLength(
final List<char[]> grid, final Coordinate start, final Coordinate end) {
final Queue<State> queue = new PriorityQueue<>(Comparator.comparingInt(State::steps));
queue.add(new State(start, 0));

final Set<Coordinate> lookAheadCache = new HashSet<>();

while (!queue.isEmpty()) {
final State state = queue.poll();
final Coordinate coordinate = state.coordinate();

if (coordinate.equals(end)) {
return state.steps();
}

for (final Coordinate next :
List.of(
new Coordinate(coordinate.x(), coordinate.y() - 1),
new Coordinate(coordinate.x(), coordinate.y() + 1),
new Coordinate(coordinate.x() - 1, coordinate.y()),
new Coordinate(coordinate.x() + 1, coordinate.y()))) {
if (grid.get(next.y())[next.x()] != '#' && !lookAheadCache.contains(next)) {
lookAheadCache.add(next);
queue.add(new State(next, state.steps() + 1));
}
}
}

return Integer.MAX_VALUE;
}

private record Target(char name, Coordinate coordinate) {}

private record Coordinate(int x, int y) {}

private record State(Coordinate coordinate, int steps) {}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
package org.ck.adventofcode.year2016;

import org.ck.adventofcode.util.BaseAOCTest;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class Day24Test extends BaseAOCTest {
@ParameterizedTest
@ValueSource(strings = {"01", "01a"})
@Disabled
void testOne(String name) throws Exception {
runTest(new Day24()::partOne, "day24/%s".formatted(name));
}

@ParameterizedTest
@ValueSource(strings = {"02"})
@Disabled
void testTwo(String name) throws Exception {
runTest(new Day24()::partTwo, "day24/%s".formatted(name));
}
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1 +1 @@
0
412
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0
664
Loading

0 comments on commit 4eee944

Please sign in to comment.