Skip to content

Instantly share code, notes, and snippets.

@SquireOfSoftware
Created December 11, 2021 00:14
Show Gist options
  • Save SquireOfSoftware/b9fb64867373c9fc6d4f8c4214948750 to your computer and use it in GitHub Desktop.
Save SquireOfSoftware/b9fb64867373c9fc6d4f8c4214948750 to your computer and use it in GitHub Desktop.
package advent_2021.day10;
import java.io.File;
import java.util.*;
public class Day10 {
public static void main(String[] args) {
File file = new File("day10.csv");
// File file = new File("sample.csv");
// sample part 1: 26397
// sample part 2: 288957
Day10 day10 = new Day10();
try (Scanner myReader = new Scanner(file)) {
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
day10.addData(Arrays.asList(data.split("")));
}
} catch (Exception e) {
e.fillInStackTrace();
System.err.println(e);
}
/*
part 1
find corrupt lines, that do not close properly
ignore the missing lines for now
if any of the lines end with the following
): 3 points.
]: 57 points.
}: 1197 points.
>: 25137 points.
then that is the error score for that corrupted line
find the corrupted line, calculate the error score
answer: 390993
*/
System.out.println(day10.getCorruptLinesValue());
/*
part 2
throw away the corrupt lines, find the missing lines and complete them
for each character that you use to complete it you can assign this value
): 1 point.
]: 2 points.
}: 3 points.
>: 4 points.
for each new character you can multiply the current total by 5, then add the
completion value
then sort the results and pick the middle value
answer: 2391385187
*/
System.out.println(day10.getMiddleCompletionValue());
}
enum Pair {
parenthesis("(", ")", 3, 1),
square("[", "]", 57, 2),
curly("{", "}", 1197, 3),
angle("<", ">", 25137, 4);
final String start;
final String end;
final int errorValue;
final int completionValue;
Pair(String start, String end, int errorValue, int completionValue) {
this.start = start;
this.end = end;
this.errorValue = errorValue;
this.completionValue = completionValue;
}
}
// for reference
private final List<List<String>> inputs = new ArrayList<>();
private final Map<String, Pair> startPairMap = new HashMap<>(4);
private final Map<String, Pair> endPairMap = new HashMap<>(4);
private final List<Line> processedLines = new ArrayList<>();
public Day10() {
startPairMap.put(Pair.parenthesis.start, Pair.parenthesis);
endPairMap.put(Pair.parenthesis.end, Pair.parenthesis);
startPairMap.put(Pair.square.start, Pair.square);
endPairMap.put(Pair.square.end, Pair.square);
startPairMap.put(Pair.curly.start, Pair.curly);
endPairMap.put(Pair.curly.end, Pair.curly);
startPairMap.put(Pair.angle.start, Pair.angle);
endPairMap.put(Pair.angle.end, Pair.angle);
}
public void addData(List<String> input) {
inputs.add(input);
Line line = new Line();
Stack<String> bracketStack = new Stack<>();
for (String bracket: input) {
if(startPairMap.containsKey(bracket)) {
// then we know its a start of something
bracketStack.push(bracket);
} else if (endPairMap.containsKey(bracket)) {
// then we know this is an ending bracket
// check for the last bracket and if it does not equal
// then it is corrupt
Pair type = endPairMap.get(bracket);
String currentStackValue = bracketStack.peek();
if (Objects.equals(type.start, currentStackValue)) {
// then we know its a legit thing, so let us pop it from the stack
bracketStack.pop();
} else {
// there is a mismatch and so now we need to mark the line as corrupt
// and stop the processing
line.setCorrupt(endPairMap.get(bracket));
line.addLeftOverStack(bracketStack);
break;
}
}
}
if (!bracketStack.isEmpty()) {
// we are potentially missing things
line.addLeftOverStack(bracketStack);
}
processedLines.add(line);
}
public long getCorruptLinesValue() {
long sum = 0;
for(Line line: processedLines) {
if (line.isCorrupt()) {
sum += line.getCorruptValue();
}
}
return sum;
}
public long getMiddleCompletionValue() {
List<Long> completionValues = new ArrayList<>();
for(Line line: processedLines) {
if (!line.isCorrupt() && line.isMissing()) {
Stack<String> leftOverStack = new Stack<>();
leftOverStack.addAll(line.getLeftOverStack());
long completionValue = 0;
while(!leftOverStack.isEmpty()) {
String bracket = leftOverStack.pop();
Pair type = startPairMap.get(bracket);
completionValue *= 5; // as per spec
completionValue += type.completionValue;
}
completionValues.add(completionValue);
}
}
completionValues.sort(Long::compareTo);
int median = completionValues.size() % 2 == 1 ? completionValues.size() / 2 + 1 : completionValues.size();
// the counts are different to positions, so you need to subtract 1
median--;
return completionValues.get(median);
}
private static class Line {
private Stack<String> bracketStack = new Stack<>();
private Pair corruptCharacter = null;
public void setCorrupt(Pair type) {
this.corruptCharacter = type;
}
public boolean isCorrupt() {
return corruptCharacter != null;
}
public int getCorruptValue() {
return corruptCharacter.errorValue;
}
public void addLeftOverStack(Stack<String> bracketStack) {
this.bracketStack = bracketStack;
}
public boolean isMissing() {
return !bracketStack.isEmpty();
}
public Stack<String> getLeftOverStack() {
return bracketStack;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment