From 372398b6456769e28a26da8b20504488b75a740b Mon Sep 17 00:00:00 2001 From: Flashk Date: Mon, 16 Dec 2024 07:02:20 +0100 Subject: [PATCH] feat: solve day 16 WIP --- .../adventofcode/flashk/day16/Movement.java | 19 +++ .../flashk/day16/ReindeerMaze.java | 124 ++++++++++++++++++ .../com/adventofcode/flashk/day16/Tile.java | 45 +++++++ .../adventofcode/flashk/day16/Day16Test.java | 28 +++- src/test/resources/inputs | 2 +- 5 files changed, 211 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/adventofcode/flashk/day16/Movement.java create mode 100644 src/main/java/com/adventofcode/flashk/day16/ReindeerMaze.java create mode 100644 src/main/java/com/adventofcode/flashk/day16/Tile.java diff --git a/src/main/java/com/adventofcode/flashk/day16/Movement.java b/src/main/java/com/adventofcode/flashk/day16/Movement.java new file mode 100644 index 0000000..83d16ed --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day16/Movement.java @@ -0,0 +1,19 @@ +package com.adventofcode.flashk.day16; + +import com.adventofcode.flashk.common.Vector2; + +public class Movement { + + private Tile tile; + private Vector2 direction; + private boolean rotate; + + public Vector2 getDirection() { + if(rotate) { + return new Vector2(0,0); + } + return new Vector2(direction); + } + + +} diff --git a/src/main/java/com/adventofcode/flashk/day16/ReindeerMaze.java b/src/main/java/com/adventofcode/flashk/day16/ReindeerMaze.java new file mode 100644 index 0000000..f4c4c2c --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day16/ReindeerMaze.java @@ -0,0 +1,124 @@ +package com.adventofcode.flashk.day16; + +import com.adventofcode.flashk.common.Vector2; + +import java.util.HashSet; +import java.util.PriorityQueue; +import java.util.Set; + +public class ReindeerMaze { + + private static final char WALL = '#'; + + private Tile[][] map; + private int rows; + private int cols; + private Vector2 startPos; + private Vector2 endPos; + private Tile startTile; + + private Set directions = Set.of(Vector2.right(), Vector2.left(), Vector2.up(), Vector2.down()); + + public ReindeerMaze(char[][] inputs) { + rows = inputs.length; + cols = inputs[0].length; + map = new Tile[rows][cols]; + + for(int row = 0; row < rows; row++) { + for(int col = 0; col < cols; col++) { + map[row][col] = new Tile(new Vector2(col, row), inputs[row][col]); + if(map[row][col].isStart()) { + startPos = map[row][col].getPosition(); + startTile = map[row][col]; + } else if(map[row][col].isEnd()) { + endPos = map[row][col].getPosition(); + } + } + } + + } + + // Rehacer con cola de prioridad + + public long solveA2() { + PriorityQueue tiles = new PriorityQueue<>(); + + + // inicio + startTile.setScore(0); + tiles.add(startTile); + while(!tiles.isEmpty()) { + Tile nextTile = tiles.poll(); + nextTile.setVisited(true); + + // Calcular adyacentes. + Set adjacentTiles = getAdjacents(nextTile); + } + } + + private Set getAdjacents(Tile nextTile) { + + } + + public long solveA() { + long result = findPath(new Vector2(startPos), Vector2.right(), 0, Long.MAX_VALUE); + + //paint(); + return result; + } + + // Casos base + // - Llegar a E + // - Llegar a un wall + + private long findPath(Vector2 position, Vector2 direction, long score, long bestScore) { + if(map[position.getY()][position.getX()].isWall()) { + return Long.MAX_VALUE; + } else if(map[position.getY()][position.getX()].isVisited()) { + return Long.MAX_VALUE; // o puede que score, pero no queremos bucles infinitos + } else if(map[position.getY()][position.getX()].isEnd()) { + /*if(score < bestScore) { + System.out.println("Result: "+score); + paint(); + }*/ + return Math.min(score, bestScore); + } + + // Calcular adyacentes + // - 4 posibles movimientos horizontales + // - 2 posibles giros: izquierda, derecha, no tiene sentido girar 180ยบ + map[position.getY()][position.getX()].setVisited(true); + + long newBestScore = bestScore; + for(Vector2 newDir :directions) { + + long additionalScore = direction.equals(newDir) ? 1 : 1001; + Vector2 newPos = Vector2.transform(position, newDir); + + + if(!map[newPos.getY()][newPos.getX()].isVisited()) { + long newScore = findPath(newPos, newDir, score + additionalScore, bestScore); + newBestScore = Math.min(newScore, newBestScore); + } + } + + map[position.getY()][position.getX()].setVisited(false); + + return newBestScore; + + } + + + private void paint(){ + for(int row = 0; row < rows; row++) { + for(int col = 0; col < cols; col++) { + if(map[row][col].isVisited()) { + System.out.print('O'); + } else { + System.out.print(map[row][col].getValue()); + } + } + System.out.println(); + } + } +} diff --git a/src/main/java/com/adventofcode/flashk/day16/Tile.java b/src/main/java/com/adventofcode/flashk/day16/Tile.java new file mode 100644 index 0000000..eb4bc14 --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day16/Tile.java @@ -0,0 +1,45 @@ +package com.adventofcode.flashk.day16; + +import com.adventofcode.flashk.common.Vector2; +import lombok.Getter; +import lombok.Setter; +import org.jetbrains.annotations.NotNull; + +@Getter +public class Tile implements Comparable{ + + private static final char WALL = '#'; + private static final char START = 'S'; + private static final char END = 'E'; + + private final Vector2 position; + private final char value; + + @Setter + private boolean visited = false; + @Setter + private long score = Long.MAX_VALUE; + + + public Tile(Vector2 position, char value) { + this.position = position; + this.value = value; + } + + public boolean isWall() { + return value == WALL; + } + + public boolean isStart(){ + return value == START; + } + + public boolean isEnd() { + return value == END; + } + + @Override + public int compareTo(@NotNull Tile o) { + return Long.compare(this.score, o.score); + } +} diff --git a/src/test/java/com/adventofcode/flashk/day16/Day16Test.java b/src/test/java/com/adventofcode/flashk/day16/Day16Test.java index 6c3b7c0..d00c5fb 100644 --- a/src/test/java/com/adventofcode/flashk/day16/Day16Test.java +++ b/src/test/java/com/adventofcode/flashk/day16/Day16Test.java @@ -34,9 +34,24 @@ public class Day16Test 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); + ReindeerMaze reindeerMaze = new ReindeerMaze(inputs); - assertEquals(0L,0L); + assertEquals(7036L,reindeerMaze.solveA()); + } + + @Test + @Order(1) + @Tag(TestTag.PART_1) + @Tag(TestTag.SAMPLE) + @DisplayName(TestDisplayName.PART_1_SAMPLE) + public void testSolvePart1Sample2() { + + // Read input file + char[][] inputs = Input.read2DCharArray(INPUT_FOLDER, TestFilename.INPUT_FILE_SINGLE_SAMPLE_2); + ReindeerMaze reindeerMaze = new ReindeerMaze(inputs); + + assertEquals(11048L,reindeerMaze.solveA()); } @Test @@ -47,9 +62,10 @@ public void testSolvePart1Sample() { public void testSolvePart1Input() { // Read input file - List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE); + char[][] inputs = Input.read2DCharArray(INPUT_FOLDER, TestFilename.INPUT_FILE); + ReindeerMaze reindeerMaze = new ReindeerMaze(inputs); - System.out.println("Solution: "); + System.out.println("Solution: "+reindeerMaze.solveA()); assertEquals(0L,0L); } @@ -62,7 +78,7 @@ public void testSolvePart1Input() { public void testSolvePart2Sample() { // 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); } @@ -75,7 +91,7 @@ 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); System.out.println("Solution: "); assertEquals(0L,0L); diff --git a/src/test/resources/inputs b/src/test/resources/inputs index f0b2beb..3314054 160000 --- a/src/test/resources/inputs +++ b/src/test/resources/inputs @@ -1 +1 @@ -Subproject commit f0b2beba9015b88138c368e4e66c4742e421ea8c +Subproject commit 3314054efc9baff6b6ab65ede53ec9474200ca88