diff --git a/2021/README.md b/2021/README.md index 52bb9049992e5bbf6f451dce949fc549071cdbf1..cd2668e400cb1f9bea7e808ca1889ffddd9aca72 100644 --- a/2021/README.md +++ b/2021/README.md @@ -114,3 +114,10 @@ either side? - We'll go for a finite element approach. Hmm. Part 2 takes a few seconds, but no surprise there -- it's now O(n^5). + +## Day 10 + +This looks like a job for a stack! + +Update: Yes, yes it was a job for a stack. Some maps simplified matters but +were not essential. diff --git a/2021/src/main/java/edu/unl/cse/bohn/Main.java b/2021/src/main/java/edu/unl/cse/bohn/Main.java index c1a7573dd7ffa665d51df86b0f5fc22fc329fc95..875e4b596eeab33d66f361eb9a25d3ac23ef04c5 100644 --- a/2021/src/main/java/edu/unl/cse/bohn/Main.java +++ b/2021/src/main/java/edu/unl/cse/bohn/Main.java @@ -8,7 +8,7 @@ public class Main { public static final String defaultApiKey = "aoc"; private static String getUserInput(String prompt, String defaultValue, Scanner scanner) { - System.out.print(prompt + "[" + defaultValue + "]: "); + System.out.print(prompt + " [" + defaultValue + "]: "); String userInput = scanner.nextLine(); return userInput.equals("") ? defaultValue : userInput; } diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day10.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day10.java new file mode 100644 index 0000000000000000000000000000000000000000..bd850389dff7fe5cc93ffd8152c569105f687a5c --- /dev/null +++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day10.java @@ -0,0 +1,103 @@ +package edu.unl.cse.bohn.year2021; + +import edu.unl.cse.bohn.Puzzle; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +@SuppressWarnings("unused") +public class Day10 extends Puzzle { + private final Map<Character, Character> chunkPartners; + private final Map<Character, Long> corruptionScores; + private final Map<Character, Long> completionScores; + private final Set<String> corruptedLines; + + public Day10(boolean isProductionReady) { + super(isProductionReady); + sampleData = """ + [({(<(())[]>[[{[]{<()<>> + [(()[<>])]({[<{<<[]>>( + {([(<{}[<>[]}>{[]{[(<()> + (((({<>}<{<{<>}{[]{[]{} + [[<[([]))<([[{}[[()]]] + [{[{({}]{}}([{[{{{}}([] + {<[[]]>}<{[{[{[]{()[[[] + [<(<(<(<{}))><([]([]() + <{([([[(<>()){}]>(<<{{ + <{([{{}}[<[[[<>{}]]]>[]]"""; + chunkPartners = new HashMap<>(); + chunkPartners.put('(', ')'); + chunkPartners.put('[', ']'); + chunkPartners.put('{', '}'); + chunkPartners.put('<', '>'); + corruptionScores = new HashMap<>(); + corruptionScores.put(')', 3L); + corruptionScores.put(']', 57L); + corruptionScores.put('}', 1197L); + corruptionScores.put('>', 25137L); + completionScores = new HashMap<>(); + completionScores.put(')', 1L); + completionScores.put(']', 2L); + completionScores.put('}', 3L); + completionScores.put('>', 4L); + corruptedLines = new HashSet<>(); + } + + @Override + public long computePart1(List<String> data) { + Long syntaxErrorScore = 0L; + Set<Character> chunkOpeners = chunkPartners.keySet(); + for (String line : data) { + Stack<Character> openChunks = new Stack<>(); + boolean errorFound = false; + int i = 0; + while (!errorFound && i < line.length()) { + char c = line.charAt(i++); + if (chunkOpeners.contains(c)) { + openChunks.push(c); + } else { + char partner = openChunks.pop(); + if (c != chunkPartners.get(partner)) { + errorFound = true; + corruptedLines.add(line); + syntaxErrorScore += corruptionScores.get(c); + } + } + } + } + return syntaxErrorScore; + } + + @Override + public long computePart2(List<String> data) { + Set<String> uncorruptedLines = new HashSet<>(data); + uncorruptedLines.removeAll(corruptedLines); + List<Long> lineScores = new LinkedList<>(); + Set<Character> chunkOpeners = chunkPartners.keySet(); + for (String line : uncorruptedLines) { + long lineScore = 0L; + Stack<Character> openChunks = new Stack<>(); + for (char c : line.toCharArray()) { + if (chunkOpeners.contains(c)) { + openChunks.push(c); + } else { + openChunks.pop(); + } + } + while (!openChunks.empty()) { + char c = openChunks.pop(); + lineScore = lineScore * 5 + completionScores.get(chunkPartners.get(c)); + } + if (lineScore > 0) { + lineScores.add(lineScore); + } + } + lineScores.sort(null); + return lineScores.get(lineScores.size() / 2); + } +}