Day 5 assignment
Satisfied with their search on Ceres, the squadron of scholars suggests subsequently scanning the stationery stacks of sub-basement 17.
The North Pole printing department is busier than ever this close to Christmas, and while The Historians continue their search of this historically significant facility, an Elf operating a very familiar printer beckons you over.
Solution in Java
Full source can be found: in GitHub
For todays solution I first created a small little reader that parses the input string into entries I can work with for both parts. Splitting out the priority queue, so the pages that must be preceded by other pages. As well as all the printing instructions.
1public void readInput() {
2 priorityMap.clear();
3 printOrders.clear();
4
5 inputLoader.consumeLine(line -> {
6 if (line.contains(",")) {
7 printOrders.add(List.of(line.split(",")));
8 } else if (line.contains("|")) {
9 var split = line.split("\\|");
10 priorityMap.computeIfAbsent(split[1].trim(), s -> new HashSet<>())
11 .add(split[0].trim());
12 }
13 });
14}
Part 1
For the first part of today I looped over each of the printing lines to filter out only those that are actually valid, using the printQueueValid
method. This method essentially attempts to look at each page in the list and makes sure that if there are any required preceding pages they are actually ahead of it in the list.
Then we take the middle element of each valid printing instruction and sum those all. As can be seen on line 4 and line 6.
1public void part1() {
2 var result = printOrders.stream()
3 .filter(this::printQueueValid)
4 .map(orderSet -> orderSet.get(orderSet.size() / 2))
5 .mapToInt(Integer::parseInt)
6 .sum();
7
8 validator.part1(result);
9}
10
11private boolean printQueueValid(List<String> pagePrintOrder) {
12 for (var idx = 0; idx < pagePrintOrder.size(); idx++) {
13 var page = pagePrintOrder.get(idx);
14
15 var constIdx = idx;
16 var errorInQueue = priorityMap.getOrDefault(page, Set.of())
17 .stream()
18 .anyMatch(precedingPage -> pagePrintOrder.indexOf(precedingPage) > constIdx);
19 if (errorInQueue) {
20 return false;
21 }
22 }
23
24 log.debug("Found valid order: {}", pagePrintOrder);
25 return true;
26}
Part 2
Whilst thinking about part 2 I created a very naïve sorting comparator to re-order the pages in the correct order using the rules stored in the priorityMap
.
For the input provided for Advent of Code this simple approach works, but if you attempt to use this on a printing queue that after the initial sorting still would contain a violation or in cases where sorting would cause new violations. Essentially for Advent of Code this sorting works correctly, since the input is very forgiving and only contains simple errors in the printing queue.
1public void part2() {
2 var result = printOrders.stream()
3 .filter(orderSet -> !printQueueValid(orderSet))
4 .map(this::reorderToValid)
5 .map(orderSet -> orderSet.get(orderSet.size() / 2))
6 .mapToInt(Integer::parseInt)
7 .sum();
8
9 validator.part2(result);
10}
11
12private List<String> reorderToValid(List<String> incorrectPrintOrder) {
13 return incorrectPrintOrder.stream()
14 .sorted(priorityComparator)
15 .toList();
16}