From 60d69582a215fd4fd68ddf8fed23174f6972188d Mon Sep 17 00:00:00 2001 From: Flashk Date: Thu, 5 Dec 2024 07:21:44 +0100 Subject: [PATCH] feat: solve day 5 --- README.md | 2 +- .../flashk/day05/PageComparator.java | 37 +++++++++++ .../adventofcode/flashk/day05/PrintQueue.java | 59 +++++++++++++++++ .../com/adventofcode/flashk/day05/README.md | 2 +- .../com/adventofcode/flashk/day05/Update.java | 64 +++++++++++++++++++ .../adventofcode/flashk/day05/Day05Test.java | 22 +++++-- src/test/resources/inputs | 2 +- 7 files changed, 178 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/adventofcode/flashk/day05/PageComparator.java create mode 100644 src/main/java/com/adventofcode/flashk/day05/PrintQueue.java create mode 100644 src/main/java/com/adventofcode/flashk/day05/Update.java diff --git a/README.md b/README.md index 1c7e95d..8ebd95a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ - [Day 2 - Red-Nosed Reports](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day02) - [Day 3 - Mull It Over](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day03) - [Day 4 - Ceres Search](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day04) -- [Day 5](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day05) +- [Day 5 - Print Queue](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day05) - [Day 6](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day06) - [Day 7](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day07) - [Day 8](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day08) diff --git a/src/main/java/com/adventofcode/flashk/day05/PageComparator.java b/src/main/java/com/adventofcode/flashk/day05/PageComparator.java new file mode 100644 index 0000000..a79ec4c --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day05/PageComparator.java @@ -0,0 +1,37 @@ +package com.adventofcode.flashk.day05; + +import java.util.Collections; +import java.util.Comparator; +import java.util.Map; +import java.util.Set; + +public class PageComparator implements Comparator { + + private final Map> orderingRules; + + public PageComparator(Map> orderingRules) { + this.orderingRules = orderingRules; + } + + @Override + public int compare(Integer o1, Integer o2) { + + // -1 si o1 precede a o2 + // 1 si o2 precede a o1 + // Resto de casos: 0 + + Set afterPagesO1 = orderingRules.getOrDefault(o1, Collections.emptySet()); + + if(afterPagesO1.contains(o2)) { + return -1; + } + + Set afterPagesO2 = orderingRules.getOrDefault(o2, Collections.emptySet()); + + if(afterPagesO2.contains(o1)) { + return 1; + } + + return 0; + } +} diff --git a/src/main/java/com/adventofcode/flashk/day05/PrintQueue.java b/src/main/java/com/adventofcode/flashk/day05/PrintQueue.java new file mode 100644 index 0000000..1a787d6 --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day05/PrintQueue.java @@ -0,0 +1,59 @@ +package com.adventofcode.flashk.day05; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class PrintQueue { + + private final Map> orderingRules = new HashMap<>(); + private final List updates = new ArrayList<>(); + + public PrintQueue(List inputs) { + boolean isUpdate = false; + for(String input : inputs) { + if(StringUtils.isBlank(input)) { + isUpdate = true; + continue; + } + + if(!isUpdate) { + String[] keyValue = input.split("\\|"); + + Integer key = Integer.valueOf(keyValue[0]); + Integer value = Integer.valueOf(keyValue[1]); + + if(orderingRules.containsKey(key)){ + orderingRules.get(key).add(value); + } else { + Set values = new HashSet<>(); + values.add(value); + orderingRules.put(key, values); + } + } else { + updates.add(new Update(input)); + } + } + } + + + public long solveA() { + return updates.stream() + .filter(update -> update.isOrderedBy(orderingRules)) + .mapToInt(Update::getMiddlePage) + .sum(); + } + + public long solveB() { + PageComparator comparator = new PageComparator(orderingRules); + return updates.stream() + .filter(update -> !update.isOrderedBy(orderingRules)) + .mapToInt(update -> update.order(comparator)) + .sum(); + } +} diff --git a/src/main/java/com/adventofcode/flashk/day05/README.md b/src/main/java/com/adventofcode/flashk/day05/README.md index af92090..b7966fb 100644 --- a/src/main/java/com/adventofcode/flashk/day05/README.md +++ b/src/main/java/com/adventofcode/flashk/day05/README.md @@ -1,3 +1,3 @@ -# Day 5: +# Day 5: Print Queue [https://adventofcode.com/2024/day/5](https://adventofcode.com/2024/day/5) diff --git a/src/main/java/com/adventofcode/flashk/day05/Update.java b/src/main/java/com/adventofcode/flashk/day05/Update.java new file mode 100644 index 0000000..ab23371 --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day05/Update.java @@ -0,0 +1,64 @@ +package com.adventofcode.flashk.day05; + +import lombok.Getter; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +public class Update { + + private List pages; + + @Getter + private int middlePage; + + public Update(String input) { + pages = Arrays.stream(input.split(",")).map(Integer::valueOf).toList(); + middlePage = pages.get(pages.size()/2); + } + + public boolean isOrderedBy(Map> orderingRules) { + + boolean isOrdered = true; + + int i = 0; + while(isOrdered && i < pages.size()) { + int page = pages.get(i); + isOrdered = isOrdered(i, orderingRules.getOrDefault(page, new HashSet<>())); + i++; + } + + return isOrdered; + } + + public int order(PageComparator comparator) { + + pages = pages.stream().sorted(comparator).toList(); + middlePage = pages.get(pages.size()/2); + + return middlePage; + } + + private boolean isOrdered(int pageIndex, Set orderingRules) { + + if(orderingRules.isEmpty()) { + return true; + } + + boolean isOrdered = true; + int i = pageIndex-1; + + // Look back + while(isOrdered && i >= 0) { + int previousPage = pages.get(i); + isOrdered = !orderingRules.contains(previousPage); + i--; + } + + return isOrdered; + } +} diff --git a/src/test/java/com/adventofcode/flashk/day05/Day05Test.java b/src/test/java/com/adventofcode/flashk/day05/Day05Test.java index 91cd29f..ec21b23 100644 --- a/src/test/java/com/adventofcode/flashk/day05/Day05Test.java +++ b/src/test/java/com/adventofcode/flashk/day05/Day05Test.java @@ -3,7 +3,6 @@ import java.util.List; import org.junit.jupiter.api.BeforeAll; -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; @@ -19,12 +18,13 @@ import com.adventofcode.flashk.common.test.utils.Timer; import com.adventofcode.flashk.common.test.utils.Input; +import static org.junit.jupiter.api.Assertions.assertEquals; + @DisplayName(TestDisplayName.DAY_05) @TestMethodOrder(OrderAnnotation.class) -@Disabled // TODO Remove comment when implemented public class Day05Test extends PuzzleTest { - private final static String INPUT_FOLDER = TestFolder.DAY_05; + private static final String INPUT_FOLDER = TestFolder.DAY_05; @BeforeAll public static void beforeAll() { @@ -43,7 +43,9 @@ public void testSolvePart1Sample() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE); - + PrintQueue printQueue = new PrintQueue(inputs); + + assertEquals(143, printQueue.solveA()); } @Test @@ -57,7 +59,9 @@ public void testSolvePart1Input() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE); - + PrintQueue printQueue = new PrintQueue(inputs); + + assertEquals(5747, printQueue.solveA()); } @Test @@ -71,7 +75,9 @@ public void testSolvePart2Sample() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE); - + PrintQueue printQueue = new PrintQueue(inputs); + + assertEquals(123, printQueue.solveB()); } @Test @@ -85,7 +91,9 @@ public void testSolvePart2Input() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE); - + PrintQueue printQueue = new PrintQueue(inputs); + + assertEquals(5502, printQueue.solveB()); } } diff --git a/src/test/resources/inputs b/src/test/resources/inputs index cb76b0a..1d9b856 160000 --- a/src/test/resources/inputs +++ b/src/test/resources/inputs @@ -1 +1 @@ -Subproject commit cb76b0a2c0a3146454ad213e1e6f944c361b8f65 +Subproject commit 1d9b8561b452fd8c4329321ebfe068cf35e645c3