Skip to content

Commit

Permalink
AoC 2023 Day 23 - java
Browse files Browse the repository at this point in the history
  • Loading branch information
pareronia committed Dec 23, 2023
1 parent ae0f4fa commit 5861327
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
| ---| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| python3 | [](src/main/python/AoC2023_01.py) | [](src/main/python/AoC2023_02.py) | [](src/main/python/AoC2023_03.py) | [](src/main/python/AoC2023_04.py) | [](src/main/python/AoC2023_05.py) | [](src/main/python/AoC2023_06.py) | [](src/main/python/AoC2023_07.py) | [](src/main/python/AoC2023_08.py) | [](src/main/python/AoC2023_09.py) | [](src/main/python/AoC2023_10.py) | [](src/main/python/AoC2023_11.py) | [](src/main/python/AoC2023_12.py) | [](src/main/python/AoC2023_13.py) | [](src/main/python/AoC2023_14.py) | [](src/main/python/AoC2023_15.py) | [](src/main/python/AoC2023_16.py) | [](src/main/python/AoC2023_17.py) | [](src/main/python/AoC2023_18.py) | [](src/main/python/AoC2023_19.py) | [](src/main/python/AoC2023_20.py) | [](src/main/python/AoC2023_21.py) | | | | |
| java | [](src/main/java/AoC2023_01.java) | [](src/main/java/AoC2023_02.java) | [](src/main/java/AoC2023_03.java) | [](src/main/java/AoC2023_04.java) | [](src/main/java/AoC2023_05.java) | [](src/main/java/AoC2023_06.java) | [](src/main/java/AoC2023_07.java) | [](src/main/java/AoC2023_08.java) | [](src/main/java/AoC2023_09.java) | [](src/main/java/AoC2023_10.java) | [](src/main/java/AoC2023_11.java) | [](src/main/java/AoC2023_12.java) | [](src/main/java/AoC2023_13.java) | [](src/main/java/AoC2023_14.java) | [](src/main/java/AoC2023_15.java) | [](src/main/java/AoC2023_16.java) | [](src/main/java/AoC2023_17.java) | [](src/main/java/AoC2023_18.java) | | [](src/main/java/AoC2023_20.java) | | [](src/main/java/AoC2023_22.java) | | | |
| rust | [](src/main/rust/AoC2023_01/src/main.rs) | [](src/main/rust/AoC2023_02/src/main.rs) | [](src/main/rust/AoC2023_03/src/main.rs) | [](src/main/rust/AoC2023_04/src/main.rs) | | [](src/main/rust/AoC2023_06/src/main.rs) | [](src/main/rust/AoC2023_07/src/main.rs) | [](src/main/rust/AoC2023_08/src/main.rs) | [](src/main/rust/AoC2023_09/src/main.rs) | | | | | | [](src/main/rust/AoC2023_15/src/main.rs) | [](src/main/rust/AoC2023_16/src/main.rs) | [](src/main/rust/AoC2023_17/src/main.rs) | [](src/main/rust/AoC2023_18/src/main.rs) | [](src/main/rust/AoC2023_19/src/main.rs) | | [](src/main/rust/AoC2023_21/src/main.rs) | | | | |
| rust | [](src/main/rust/AoC2023_01/src/main.rs) | [](src/main/rust/AoC2023_02/src/main.rs) | [](src/main/rust/AoC2023_03/src/main.rs) | [](src/main/rust/AoC2023_04/src/main.rs) | | [](src/main/rust/AoC2023_06/src/main.rs) | [](src/main/rust/AoC2023_07/src/main.rs) | [](src/main/rust/AoC2023_08/src/main.rs) | [](src/main/rust/AoC2023_09/src/main.rs) | | | | | | [](src/main/rust/AoC2023_15/src/main.rs) | [](src/main/rust/AoC2023_16/src/main.rs) | [](src/main/rust/AoC2023_17/src/main.rs) | [](src/main/rust/AoC2023_18/src/main.rs) | [](src/main/rust/AoC2023_19/src/main.rs) | | [](src/main/rust/AoC2023_21/src/main.rs) | | [](src/main/rust/AoC2023_23/src/main.rs) | | |
<!-- @END:ImplementationsTable:2023@ -->

## 2022
Expand Down
204 changes: 204 additions & 0 deletions src/main/java/AoC2023_23.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.github.pareronia.aoc.CharGrid;
import com.github.pareronia.aoc.Grid.Cell;
import com.github.pareronia.aoc.geometry.Direction;
import com.github.pareronia.aoc.solution.Logger;
import com.github.pareronia.aoc.solution.Sample;
import com.github.pareronia.aoc.solution.Samples;
import com.github.pareronia.aoc.solution.SolutionBase;

public final class AoC2023_23
extends SolutionBase<CharGrid, Integer, Integer> {

private AoC2023_23(final boolean debug) {
super(debug);
}

public static AoC2023_23 create() {
return new AoC2023_23(false);
}

public static AoC2023_23 createDebug() {
return new AoC2023_23(true);
}

@Override
protected CharGrid parseInput(final List<String> inputs) {
return CharGrid.from(inputs);
}

@Override
public Integer solvePart1(final CharGrid grid) {
return new PathFinder(grid, this.debug)
.findLongestHikeLengthWithDownwardSlopesOnly();
}

@Override
public Integer solvePart2(final CharGrid grid) {
return new PathFinder(grid, this.debug).findLongestHikeLength();
}

@Override
@Samples({
@Sample(method = "part1", input = TEST, expected = "94"),
@Sample(method = "part2", input = TEST, expected = "154"),
})
public void samples() {
}

public static void main(final String[] args) throws Exception {
AoC2023_23.create().run();
}

static final class PathFinder {
private final CharGrid grid;
private final Cell start;
private final Cell end;
private final Logger logger;

protected PathFinder(final CharGrid grid, final boolean debug) {
this.grid = grid;
this.start = Cell.at(0, 1);
this.end = Cell.at(grid.getMaxRowIndex(), grid.getMaxColIndex() - 1);
this.logger = new Logger(debug);
}

public int findLongestHikeLength() {
final Set<Cell> pois = this.findPois();
log(pois);
final Map<Cell, Set<Edge>> graph = this.buildGraph(pois, false);
log(graph);
return this.findLongest(graph, start, end, new HashSet<>());
}

public int findLongestHikeLengthWithDownwardSlopesOnly() {
final Set<Cell> pois = this.findPois();
log(pois);
final Map<Cell, Set<Edge>> graph = this.buildGraph(pois, true);
log(graph);
return this.findLongest(graph, start, end, new HashSet<>());
}

private int findLongest(
final Map<Cell, Set<Edge>> graph,
final Cell curr,
final Cell end,
final Set<Cell> seen
) {
if (curr.equals(end)) {
return 0;
}
int ans = (int) -1e9;
seen.add(curr);
for (final Edge e : graph.get(curr)) {
if (seen.contains(e.vertex)) {
continue;
}
ans = Math.max(
ans,
e.weight + this.findLongest(graph, e.vertex, end, seen));
}
seen.remove(curr);
return ans;
}

private Set<Cell> findPois() {
final Set<Cell> ans = new HashSet<>();
this.grid.getCells().forEach(cell -> {
if (cell.equals(this.start) || cell.equals(this.end)) {
ans.add(cell);
return;
}
if (this.grid.getValue(cell) == '#') {
return;
}
if (this.grid.getCapitalNeighbours(cell)
.filter(n -> this.grid.getValue(n) != '#')
.count() > 2) {
ans.add(cell);
}
});
return ans;
}

record Edge(Cell vertex, int weight) {}

private Map<Cell, Set<Edge>> buildGraph(
final Set<Cell> pois, final boolean downwardSlopesOnly
) {
record State(Cell cell, int distance) {}

final Map<Cell, Set<Edge>> edges = new HashMap<>();
for (final Cell poi : pois) {
final Deque<State> q = new ArrayDeque<>(Set.of(new State(poi, 0)));
final Set<Cell> seen = new HashSet<>(Set.of(poi));
while (!q.isEmpty()) {
final State node = q.poll();
if (pois.contains(node.cell) && !node.cell.equals(poi)) {
edges.computeIfAbsent(poi, k -> new HashSet<>())
.add(new Edge(node.cell, node.distance));
continue;
}
for (final Direction d : Direction.CAPITAL) {
final Cell n = node.cell.at(d);
if (!this.grid.isInBounds(n)) {
continue;
}
final char val = this.grid.getValue(n);
if (val == '#') {
continue;
}
if (downwardSlopesOnly
&& Set.of('<', '>', 'v', '^').contains(val)
&& Direction.fromChar(val) != d) {
continue;
}
if (seen.contains(n)) {
continue;
}
seen.add(n);
q.add(new State(n, node.distance + 1));
}
}
}
return edges;
}

private void log(final Object obj) {
this.logger.log(obj);
}
}

private static final String TEST = """
#.#####################
#.......#########...###
#######.#########.#.###
###.....#.>.>.###.#.###
###v#####.#v#.###.#.###
###.>...#.#.#.....#...#
###v###.#.#.#########.#
###...#.#.#.......#...#
#####.#.#.#######.#.###
#.....#.#.#.......#...#
#.#####.#.#.#########v#
#.#...#...#...###...>.#
#.#.#v#######v###.###v#
#...#.>.#...>.>.#.###.#
#####v#.#.###v#.#.###.#
#.....#...#...#.#.#...#
#.#########.###.#.#.###
#...###...#...#...#.###
###.###.#.###v#####v###
#...#...#.#.>.>.#.>.###
#.###.###.#.###.#.#v###
#.....###...###...#...#
#####################.#
""";
}

0 comments on commit 5861327

Please sign in to comment.