Skip to content

Commit

Permalink
AoC 2024 Day 12 - java
Browse files Browse the repository at this point in the history
  • Loading branch information
pareronia committed Dec 12, 2024
1 parent e406ad8 commit 9696371
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| ---| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| python3 | [](src/main/python/AoC2024_01.py) | [](src/main/python/AoC2024_02.py) | [](src/main/python/AoC2024_03.py) | [](src/main/python/AoC2024_04.py) | [](src/main/python/AoC2024_05.py) | [](src/main/python/AoC2024_06.py) | [](src/main/python/AoC2024_07.py) | [](src/main/python/AoC2024_08.py) | [](src/main/python/AoC2024_09.py) | [](src/main/python/AoC2024_10.py) | [](src/main/python/AoC2024_11.py) | [](src/main/python/AoC2024_12.py) | | | | | | | | | | | | | |
| java | [](src/main/java/AoC2024_01.java) | [](src/main/java/AoC2024_02.java) | [](src/main/java/AoC2024_03.java) | [](src/main/java/AoC2024_04.java) | [](src/main/java/AoC2024_05.java) | [](src/main/java/AoC2024_06.java) | [](src/main/java/AoC2024_07.java) | [](src/main/java/AoC2024_08.java) | | [](src/main/java/AoC2024_10.java) | [](src/main/java/AoC2024_11.java) | | | | | | | | | | | | | | |
| java | [](src/main/java/AoC2024_01.java) | [](src/main/java/AoC2024_02.java) | [](src/main/java/AoC2024_03.java) | [](src/main/java/AoC2024_04.java) | [](src/main/java/AoC2024_05.java) | [](src/main/java/AoC2024_06.java) | [](src/main/java/AoC2024_07.java) | [](src/main/java/AoC2024_08.java) | | [](src/main/java/AoC2024_10.java) | [](src/main/java/AoC2024_11.java) | [](src/main/java/AoC2024_12.java) | | | | | | | | | | | | | |
| rust | [](src/main/rust/AoC2024_01/src/main.rs) | [](src/main/rust/AoC2024_02/src/main.rs) | [](src/main/rust/AoC2024_03/src/main.rs) | [](src/main/rust/AoC2024_04/src/main.rs) | [](src/main/rust/AoC2024_05/src/main.rs) | [](src/main/rust/AoC2024_06/src/main.rs) | [](src/main/rust/AoC2024_07/src/main.rs) | [](src/main/rust/AoC2024_08/src/main.rs) | | | | | | | | | | | | | | | | | |
<!-- @END:ImplementationsTable:2024@ -->

Expand Down
170 changes: 170 additions & 0 deletions src/main/java/AoC2024_12.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import static com.github.pareronia.aoc.IntegerSequence.Range.range;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.ToIntBiFunction;

import com.github.pareronia.aoc.Grid.Cell;
import com.github.pareronia.aoc.Utils;
import com.github.pareronia.aoc.geometry.Direction;
import com.github.pareronia.aoc.graph.BFS;
import com.github.pareronia.aoc.solution.Sample;
import com.github.pareronia.aoc.solution.Samples;
import com.github.pareronia.aoc.solution.SolutionBase;

public final class AoC2024_12 extends SolutionBase<List<String>, Integer, Integer> {

private static final List<List<Direction>> CORNER_DIRS = List.of(
List.of(Direction.LEFT_AND_UP, Direction.LEFT, Direction.UP),
List.of(Direction.RIGHT_AND_UP, Direction.RIGHT, Direction.UP),
List.of(Direction.RIGHT_AND_DOWN, Direction.RIGHT, Direction.DOWN),
List.of(Direction.LEFT_AND_DOWN, Direction.LEFT, Direction.DOWN)
);

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

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

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

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

private int solve(
final List<String> input,
final ToIntBiFunction<Cell, Set<Cell>> count
) {
final Map<Character, Set<Cell>> plotsByPlant = new HashMap<>();
range(input.size()).forEach(r ->
range(input.get(r).length()).forEach(c ->
plotsByPlant
.computeIfAbsent(input.get(r).charAt(c), k -> new HashSet<>())
.add(Cell.at(r, c))));
final Iterator<Set<Cell>> regions = new Iterator<>() {
final Iterator<Character> keys = plotsByPlant.keySet().iterator();
char key = keys.next();
Set<Cell> allPlotsWithPlant = plotsByPlant.get(key);

@Override
public Set<Cell> next() {
if (allPlotsWithPlant.isEmpty()) {
key = keys.next();
allPlotsWithPlant = plotsByPlant.get(key);
}
final Set<Cell> region = BFS.floodFill(
allPlotsWithPlant.iterator().next(),
cell -> cell.capitalNeighbours()
.filter(allPlotsWithPlant::contains));
allPlotsWithPlant.removeAll(region);
return region;
}

@Override
public boolean hasNext() {
return !allPlotsWithPlant.isEmpty() || keys.hasNext();
}
};
return Utils.stream(regions)
.mapToInt(region -> region.stream()
.mapToInt(plot -> count.applyAsInt(plot, region) * region.size())
.sum())
.sum();
}

@Override
public Integer solvePart1(final List<String> input) {
final ToIntBiFunction<Cell, Set<Cell>> countEdges
= (plot, region) -> (4 - (int) plot.capitalNeighbours()
.filter(region::contains)
.count());
return solve(input, countEdges);
}

@Override
public Integer solvePart2(final List<String> input) {
final Set<int[]> matches = Set.of(
new int[] {0, 0, 0}, new int[] {1, 0, 0}, new int[] {0, 1, 1});
final ToIntBiFunction<Cell, Set<Cell>> countCorners
= (plot, region) -> ((int) CORNER_DIRS.stream()
.filter(d -> {
final int[] test = range(3).intStream()
.map(i -> region.contains(plot.at(d.get(i))) ? 1 : 0)
.toArray();
return matches.stream().anyMatch(m -> Arrays.equals(m, test));
})
.count());
return solve(input, countCorners);
}

@Override
@Samples({
@Sample(method = "part1", input = TEST1, expected = "140"),
@Sample(method = "part1", input = TEST2, expected = "772"),
@Sample(method = "part1", input = TEST3, expected = "1930"),
@Sample(method = "part2", input = TEST1, expected = "80"),
@Sample(method = "part2", input = TEST2, expected = "436"),
@Sample(method = "part2", input = TEST3, expected = "1206"),
@Sample(method = "part2", input = TEST4, expected = "236"),
@Sample(method = "part2", input = TEST5, expected = "368"),
})
public void samples() {
}

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

private static final String TEST1 = """
AAAA
BBCD
BBCC
EEEC
""";
private static final String TEST2 = """
OOOOO
OXOXO
OOOOO
OXOXO
OOOOO
""";
private static final String TEST3 = """
RRRRIICCFF
RRRRIICCCF
VVRRRCCFFF
VVRCCCJFFF
VVVVCJJCFE
VVIVCCJJEE
VVIIICJJEE
MIIIIIJJEE
MIIISIJEEE
MMMISSJEEE
""";
private static final String TEST4 = """
EEEEE
EXXXX
EEEEE
EXXXX
EEEEE
""";
private static final String TEST5 = """
AAAAAA
AAABBA
AAABBA
ABBAAA
ABBAAA
AAAAAA
""";
}

0 comments on commit 9696371

Please # to comment.