From bd6166fed7d863a41d26554b92d9afad395ebe05 Mon Sep 17 00:00:00 2001 From: Flashk Date: Thu, 12 Dec 2024 07:32:22 +0100 Subject: [PATCH] feat: solve day 12 part 1 --- .../flashk/common/Array2DUtil.java | 13 ++ .../flashk/day12/GardenGroups.java | 168 ++++++++++++++++++ .../adventofcode/flashk/day12/GardenPlot.java | 27 +++ .../adventofcode/flashk/day12/Day12Test.java | 23 +-- src/test/resources/inputs | 2 +- 5 files changed, 221 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/adventofcode/flashk/day12/GardenGroups.java create mode 100644 src/main/java/com/adventofcode/flashk/day12/GardenPlot.java diff --git a/src/main/java/com/adventofcode/flashk/common/Array2DUtil.java b/src/main/java/com/adventofcode/flashk/common/Array2DUtil.java index 22543f3..1652085 100644 --- a/src/main/java/com/adventofcode/flashk/common/Array2DUtil.java +++ b/src/main/java/com/adventofcode/flashk/common/Array2DUtil.java @@ -21,6 +21,19 @@ public static char[][] transpose(char[][] array) { return transposedArray; } + /* + public static T[][] transpose(T[][] array) { + int rows = array.length; + int cols = array[0].length; + char[][] transposedArray = new char[cols][rows]; + for(int row = 0; row < rows; row++) { + for(int col = 0; col < cols; col++) { + transposedArray[col][row] = array[row][col]; + } + } + return transposedArray; + }*/ + /** * Paints the given array. * @param map the array to paint diff --git a/src/main/java/com/adventofcode/flashk/day12/GardenGroups.java b/src/main/java/com/adventofcode/flashk/day12/GardenGroups.java new file mode 100644 index 0000000..c37a24e --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day12/GardenGroups.java @@ -0,0 +1,168 @@ +package com.adventofcode.flashk.day12; + +import com.adventofcode.flashk.common.Vector2; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class GardenGroups { + + private int rows; + private int cols; + private GardenPlot[][] map; + private final Map regionAreas = new HashMap<>(); + + public GardenGroups(char[][] inputs) { + + rows = inputs.length; + cols = inputs[0].length; + map = new GardenPlot[rows][cols]; + + for(int row = 0; row < rows; row++){ + for(int col = 0; col < cols; col++) { + map[row][col] = new GardenPlot(inputs[row][col], new Vector2(col, row)); + } + } + + } + + public long solveA() { + findRegions(); + return calculatePrice(); + } + + public long solveB() { + findRegions(); + // TODO calculate sides of each region + // then calculate price + return 0L; + } + + private void findRegions() { + int regionId = 1; + for(int row = 0; row < rows; row++) { + for(int col = 0; col < cols; col++) { + if(!map[row][col].hasRegion()) { + int regionArea = findRegion(map[row][col], map[row][col].getPlant(), regionId); + regionAreas.put(regionId, regionArea); + regionId++; + } + + } + } + } + + private int findRegion(GardenPlot gardenPlot, char plant, int regionId) { + + if(gardenPlot.isVisited()) { + return 0; + } + + if(gardenPlot.hasRegion()) { + return 0; + } + + if(gardenPlot.getPlant() != plant) { + return 0; + } + + int area = 1; + gardenPlot.setVisited(true); + gardenPlot.setRegionId(regionId); + + Set adjacentPlots = getAdjacentPlots(gardenPlot); + + for(GardenPlot adjacentPlot : adjacentPlots) { + area += findRegion(adjacentPlot, plant, regionId); + } + + gardenPlot.setVisited(false); + + return area; + } + + private long calculatePrice() { + + long price = 0; + + for(int row = 0; row < rows; row++) { + + GardenPlot previousPlot = null; + for(int col = 0; col < cols;col++) { + GardenPlot plot = map[row][col]; + + if(previousPlot == null) { + price += regionAreas.get(plot.getRegionId()); + } else if(previousPlot.getRegionId() != plot.getRegionId()) { + price += regionAreas.get(previousPlot.getRegionId()); + price += regionAreas.get(plot.getRegionId()); + } + + previousPlot = plot; + } + + // Add price of right-most fence + price += regionAreas.get(previousPlot.getRegionId()); + + } + + + for(int col = 0; col < cols; col++) { + + GardenPlot previousPlot = null; + for(int row = 0; row < rows; row++) { + GardenPlot plot = map[row][col]; + + if(previousPlot == null) { + price += regionAreas.get(plot.getRegionId()); + } else if(previousPlot.getRegionId() != plot.getRegionId()) { + price += regionAreas.get(previousPlot.getRegionId()); + price += regionAreas.get(plot.getRegionId()); + } + + previousPlot = plot; + } + + // Add price of right-most fence + price += regionAreas.get(previousPlot.getRegionId()); + } + + return price; + + } + + private Set getAdjacentPlots(GardenPlot gardenPlot) { + + Set adjacentPlots = new HashSet<>(); + + Vector2 initialPos = gardenPlot.getPosition(); + + Vector2 nextPos = Vector2.transform(initialPos, Vector2.left()); + if(isInbounds(nextPos)) { + adjacentPlots.add(map[nextPos.getY()][nextPos.getX()]); + } + + nextPos = Vector2.transform(initialPos, Vector2.right()); + if(isInbounds(nextPos)) { + adjacentPlots.add(map[nextPos.getY()][nextPos.getX()]); + } + + nextPos = Vector2.transform(initialPos, Vector2.up()); + if(isInbounds(nextPos)) { + adjacentPlots.add(map[nextPos.getY()][nextPos.getX()]); + } + + nextPos = Vector2.transform(initialPos, Vector2.down()); + if(isInbounds(nextPos)) { + adjacentPlots.add(map[nextPos.getY()][nextPos.getX()]); + } + + return adjacentPlots; + } + + private boolean isInbounds(Vector2 pos) { + return (pos.getY() >= 0 && pos.getY() < rows && pos.getX() >= 0 && pos.getX() < cols); + } +} diff --git a/src/main/java/com/adventofcode/flashk/day12/GardenPlot.java b/src/main/java/com/adventofcode/flashk/day12/GardenPlot.java new file mode 100644 index 0000000..28ad46b --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day12/GardenPlot.java @@ -0,0 +1,27 @@ +package com.adventofcode.flashk.day12; + +import com.adventofcode.flashk.common.Vector2; +import lombok.Getter; +import lombok.Setter; + +@Getter +public class GardenPlot { + + private char plant; + + @Setter + private int regionId = 0; + private Vector2 position; + + @Setter + private boolean visited = false; + + public GardenPlot(char plant, Vector2 position) { + this.plant = plant; + this.position = position; + } + + public boolean hasRegion() { + return regionId != 0; + } +} diff --git a/src/test/java/com/adventofcode/flashk/day12/Day12Test.java b/src/test/java/com/adventofcode/flashk/day12/Day12Test.java index 628da10..fa6807c 100644 --- a/src/test/java/com/adventofcode/flashk/day12/Day12Test.java +++ b/src/test/java/com/adventofcode/flashk/day12/Day12Test.java @@ -34,9 +34,10 @@ public class Day12Test extends PuzzleTest { public void testSolvePart1Sample() { // Read input file - List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE); + char[][] inputs = Input.read2DCharArray(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE); - assertEquals(0L,0L); + GardenGroups gardenGroups = new GardenGroups(inputs); + assertEquals(1930L, gardenGroups.solveA()); } @Test @@ -47,10 +48,10 @@ public void testSolvePart1Sample() { public void testSolvePart1Input() { // Read input file - List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE); - - System.out.println("Solution: "); - assertEquals(0L,0L); + char[][] inputs = Input.read2DCharArray(INPUT_FOLDER, TestFilename.INPUT_FILE); + GardenGroups gardenGroups = new GardenGroups(inputs); + System.out.println("Solution: "+gardenGroups.solveA()); + assertEquals(1424472L,gardenGroups.solveA()); } @@ -62,9 +63,9 @@ public void testSolvePart1Input() { public void testSolvePart2Sample() { // Read input file - List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE); - - assertEquals(0L,0L); + char[][] inputs = Input.read2DCharArray(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE); + GardenGroups gardenGroups = new GardenGroups(inputs); + assertEquals(1206L,0L); } @Test @@ -75,8 +76,8 @@ public void testSolvePart2Sample() { public void testSolvePart2Input() { // Read input file - List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE); - + char[][] inputs = Input.read2DCharArray(INPUT_FOLDER, TestFilename.INPUT_FILE); + GardenGroups gardenGroups = new GardenGroups(inputs); System.out.println("Solution: "); assertEquals(0L,0L); diff --git a/src/test/resources/inputs b/src/test/resources/inputs index d6a7285..6e46751 160000 --- a/src/test/resources/inputs +++ b/src/test/resources/inputs @@ -1 +1 @@ -Subproject commit d6a72854240e7bb698341c87fe5ab7e9ec6d1dd3 +Subproject commit 6e46751aae5bf19aa90600002ebe8426959d483f