From 24f41bc5a64abdd965da69253663b477102a7cdc Mon Sep 17 00:00:00 2001 From: Flashk Date: Sat, 14 Dec 2024 09:46:17 +0100 Subject: [PATCH] feat: solve day 14 --- README.md | 2 +- .../com/adventofcode/flashk/day14/README.md | 2 +- .../flashk/day14/RestroomRedoubt.java | 92 +++++++++++++++++++ .../com/adventofcode/flashk/day14/Robot.java | 53 +++++++++++ .../adventofcode/flashk/day14/Day14Test.java | 43 ++++----- src/test/resources/inputs | 2 +- 6 files changed, 166 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/adventofcode/flashk/day14/RestroomRedoubt.java create mode 100644 src/main/java/com/adventofcode/flashk/day14/Robot.java diff --git a/README.md b/README.md index 004f641..f6deace 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ - [Day 11 - Plutonian Pebbles](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day11) - [Day 12 - Garden Groups](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day12) - [Day 13 - Claw Contraption](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day13) -- [Day 14](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day14) +- [Day 14 - Restroom Redoubt](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day14) - [Day 15](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day15) - [Day 16](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day16) - [Day 17](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day17) diff --git a/src/main/java/com/adventofcode/flashk/day14/README.md b/src/main/java/com/adventofcode/flashk/day14/README.md index 6f9e5d7..9ce9f8e 100644 --- a/src/main/java/com/adventofcode/flashk/day14/README.md +++ b/src/main/java/com/adventofcode/flashk/day14/README.md @@ -1,3 +1,3 @@ -# Day 14: +# Day 14: Restroom Redoubt [https://adventofcode.com/2024/day/14](https://adventofcode.com/2024/day/14) diff --git a/src/main/java/com/adventofcode/flashk/day14/RestroomRedoubt.java b/src/main/java/com/adventofcode/flashk/day14/RestroomRedoubt.java new file mode 100644 index 0000000..04f882d --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day14/RestroomRedoubt.java @@ -0,0 +1,92 @@ +package com.adventofcode.flashk.day14; + +import com.adventofcode.flashk.common.Collider2D; +import com.adventofcode.flashk.common.Vector2; + +import java.util.List; +import java.util.Optional; + +public class RestroomRedoubt { + + private final int rows; + private final int cols; + + private final List robots; + + public RestroomRedoubt(List inputs, int rows, int cols) { + this.rows = rows; + this.cols = cols; + robots = inputs.stream().map(Robot::new).toList(); + } + + public int solveA(int seconds) { + + int q1Robots = 0; + int q2Robots = 0; + int q3Robots = 0; + int q4Robots = 0; + + Collider2D quadrant1 = new Collider2D(new Vector2(0,0), new Vector2((cols/2)-1, (rows/2)-1)); + Collider2D quadrant2 = new Collider2D(new Vector2((cols/2)+1,0), new Vector2(cols-1, (rows/2)-1)); + Collider2D quadrant3 = new Collider2D(new Vector2(0,(rows/2)+1), new Vector2((cols/2)-1,rows-1)); + Collider2D quadrant4 = new Collider2D(new Vector2((cols/2)+1,(rows/2)+1), new Vector2(cols-1,rows-1)); + + for(Robot robot : robots) { + robot.move(seconds, rows, cols); + // quadrant1.collidesWith(robot.getPosition()) was not working. Possible reasons: + // - collidesWith(Vector2) is only checking if the point is part of a line instead of an area. + // - Didn't test diagonal test cases + if(quadrant1.collidesWith(new Collider2D(robot.getPosition()))) { + q1Robots++; + } else if(quadrant2.collidesWith(new Collider2D(robot.getPosition()))) { + q2Robots++; + } else if(quadrant3.collidesWith(new Collider2D(robot.getPosition()))) { + q3Robots++; + } else if(quadrant4.collidesWith(new Collider2D(robot.getPosition()))) { + q4Robots++; + } + } + + return q1Robots * q2Robots * q3Robots * q4Robots; + } + + public int solveB() { + int seconds = 0; + long count = -1; + + do { + seconds++; + for (Robot robot : robots) { + robot.move(rows, cols); + count = robots.stream().map(Robot::getPosition).distinct().count(); + } + } while (count != robots.size()) ; + + paint(); + + return seconds; + + } + + private void paint() { + for(int row = 0; row < rows; row++) { + for(int col = 0; col < cols; col++) { + final int x = col; + final int y = row; + Optional robot = robots.stream() + .filter(r -> r.getPosition().getX() == x) + .filter(r -> r.getPosition().getY() == y) + .distinct() + .findFirst(); + + + if(robot.isPresent()) { + System.out.print("#"); + } else { + System.out.print("."); + } + } + System.out.println(); + } + } +} diff --git a/src/main/java/com/adventofcode/flashk/day14/Robot.java b/src/main/java/com/adventofcode/flashk/day14/Robot.java new file mode 100644 index 0000000..6ef1355 --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day14/Robot.java @@ -0,0 +1,53 @@ +package com.adventofcode.flashk.day14; + +import com.adventofcode.flashk.common.Vector2; +import lombok.Getter; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Robot { + + + private static final Pattern ROBOT_PATTERN = Pattern.compile("p=(-?\\d*),(-?\\d*) v=(-?\\d*),(-?\\d*)"); + + @Getter + private Vector2 position; + private final Vector2 direction; + + public Robot(String input) { + super(); + + Matcher matcher = ROBOT_PATTERN.matcher(input); + + if(matcher.find()) { + + String px = matcher.group(1); + String py = matcher.group(2); + String vx = matcher.group(3); + String vy = matcher.group(4); + + position = new Vector2(Integer.parseInt(px), Integer.parseInt(py)); + direction = new Vector2(Integer.parseInt(vx), Integer.parseInt(vy)); + } else { + throw new IllegalArgumentException("Invalid string"); + } + + } + + public void move(int seconds, int rows, int cols) { + for(int i = 0; i < seconds; i++) { + move(rows, cols); + } + } + + public void move(int rows, int cols) { + int x1 = position.getX() + direction.getX(); + int y1 = position.getY() + direction.getY(); + int x2 = (cols + x1) % cols; + int y2 = (rows + y1) % rows; + position = new Vector2(x2,y2); + } + + +} diff --git a/src/test/java/com/adventofcode/flashk/day14/Day14Test.java b/src/test/java/com/adventofcode/flashk/day14/Day14Test.java index 523babc..dc45f40 100644 --- a/src/test/java/com/adventofcode/flashk/day14/Day14Test.java +++ b/src/test/java/com/adventofcode/flashk/day14/Day14Test.java @@ -2,7 +2,6 @@ import java.util.List; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import org.junit.jupiter.api.Order; @@ -14,29 +13,35 @@ import com.adventofcode.flashk.common.test.constants.TestFilename; import com.adventofcode.flashk.common.test.constants.TestFolder; import com.adventofcode.flashk.common.test.constants.TestTag; -import com.adventofcode.flashk.common.test.utils.PuzzleTest; import com.adventofcode.flashk.common.test.utils.Input; import static org.junit.jupiter.api.Assertions.assertEquals; @DisplayName(TestDisplayName.DAY_14) @TestMethodOrder(OrderAnnotation.class) -@Disabled // TODO Remove comment when implemented -public class Day14Test extends PuzzleTest { +class Day14Test { private static final String INPUT_FOLDER = TestFolder.DAY_14; + private static final int MAX_ROWS_SAMPLE = 7; + private static final int MAX_COLS_SAMPLE = 11; + + private static final int MAX_ROWS_INPUT = 103; + private static final int MAX_COLS_INPUT = 101; + @Test @Order(1) @Tag(TestTag.PART_1) @Tag(TestTag.SAMPLE) @DisplayName(TestDisplayName.PART_1_SAMPLE) - public void testSolvePart1Sample() { + void part1SampleTest() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE); - assertEquals(0L,0L); + RestroomRedoubt restroomRedoubt = new RestroomRedoubt(inputs, MAX_ROWS_SAMPLE, MAX_COLS_SAMPLE); + + assertEquals(12L,restroomRedoubt.solveA(100)); } @Test @@ -44,41 +49,29 @@ public void testSolvePart1Sample() { @Tag(TestTag.PART_1) @Tag(TestTag.INPUT) @DisplayName(TestDisplayName.PART_1_INPUT) - public void testSolvePart1Input() { + void part1InputTest() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE); + RestroomRedoubt restroomRedoubt = new RestroomRedoubt(inputs, MAX_ROWS_INPUT, MAX_COLS_INPUT); - System.out.println("Solution: "); - assertEquals(0L,0L); + assertEquals(214109808,restroomRedoubt.solveA(100)); } - @Test - @Order(3) - @Tag(TestTag.PART_2) - @Tag(TestTag.SAMPLE) - @DisplayName(TestDisplayName.PART_2_SAMPLE) - public void testSolvePart2Sample() { - - // Read input file - List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE); - - assertEquals(0L,0L); - } @Test - @Order(4) + @Order(3) @Tag(TestTag.PART_2) @Tag(TestTag.INPUT) @DisplayName(TestDisplayName.PART_2_INPUT) - public void testSolvePart2Input() { + void part2InputTest() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE); + RestroomRedoubt restroomRedoubt = new RestroomRedoubt(inputs, MAX_ROWS_INPUT, MAX_COLS_INPUT); - System.out.println("Solution: "); - assertEquals(0L,0L); + assertEquals(7687, restroomRedoubt.solveB()); } diff --git a/src/test/resources/inputs b/src/test/resources/inputs index f92cbf3..141e259 160000 --- a/src/test/resources/inputs +++ b/src/test/resources/inputs @@ -1 +1 @@ -Subproject commit f92cbf3a59cb1945444c1143c900e07c1f4f0f88 +Subproject commit 141e2598ad5a0b774f7068e7b7d4d737ed887e66