Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 785ff7b

Browse filesBrowse files
committed
Day 10
1 parent 84d347b commit 785ff7b
Copy full SHA for 785ff7b

File tree

Expand file treeCollapse file tree

2 files changed

+147
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+147
-0
lines changed

‎src/test/java/com/macasaet/Day10.java

Copy file name to clipboard
+137Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package com.macasaet;
2+
3+
import java.util.ArrayList;
4+
import java.util.LinkedList;
5+
import java.util.List;
6+
import java.util.stream.Stream;
7+
import java.util.stream.StreamSupport;
8+
9+
import org.junit.jupiter.api.Test;
10+
11+
/**
12+
* --- Day 10: Syntax Scoring ---
13+
*/
14+
public class Day10 {
15+
16+
protected Stream<String> getInput() {
17+
return StreamSupport
18+
.stream(new LineSpliterator("day-10.txt"),
19+
false);
20+
}
21+
22+
/**
23+
* The type of open and closing delimiter for a chunk in the navigation subsystem
24+
*/
25+
public enum BracketType {
26+
PARENTHESIS('(', ')', 3, 1),
27+
SQUARE('[', ']', 57, 2),
28+
CURLY('{', '}', 1197, 3),
29+
ANGLED('<', '>', 25137, 4);
30+
31+
private final char open;
32+
private final char close;
33+
private final int corruptionPoints;
34+
private final int autocompletePoints;
35+
36+
BracketType(char open, char close, int corruptionPoints, final int autocompletePoints) {
37+
this.open = open;
38+
this.close = close;
39+
this.corruptionPoints = corruptionPoints;
40+
this.autocompletePoints = autocompletePoints;
41+
}
42+
43+
public static BracketType forOpen(final char c) {
44+
return switch (c) {
45+
case '(' -> PARENTHESIS;
46+
case '[' -> SQUARE;
47+
case '{' -> CURLY;
48+
case '<' -> ANGLED;
49+
default -> throw new IllegalStateException("Unexpected value: " + c);
50+
};
51+
}
52+
53+
public static BracketType forClose(final char c) {
54+
return switch (c) {
55+
case ')' -> PARENTHESIS;
56+
case ']' -> SQUARE;
57+
case '}' -> CURLY;
58+
case '>' -> ANGLED;
59+
default -> throw new IllegalStateException("Unexpected value: " + c);
60+
};
61+
}
62+
}
63+
64+
/**
65+
* @param line a line in the navigation subsystem
66+
* @return a score of how corrupt the line is. A score of zero means it is not corrupt. The higher the value, the
67+
* more corrupt the line is.
68+
*/
69+
public int calculateCorruptionScore(final char[] line) {
70+
final var stack = new LinkedList<BracketType>();
71+
for (int i = 0; i < line.length; i++) {
72+
final var c = line[i];
73+
if (c == '(' || c == '[' || c == '{' || c == '<') {
74+
stack.push(BracketType.forOpen(c));
75+
} else if (c == ')' || c == ']' || c == '}' || c == '>') {
76+
if (stack.peek().close == c) {
77+
stack.pop();
78+
} else {
79+
// corrupt
80+
return BracketType.forClose(c).corruptionPoints;
81+
}
82+
}
83+
}
84+
// if stack is not empty, it's incomplete
85+
return 0;
86+
}
87+
88+
/**
89+
* @param line a non-corrupt line in the navigation subsystem. Behaviour is undefined for corrupt lines.
90+
* @return the score for the suffix required to complete the line
91+
*/
92+
public long calculateCompletionScore(final char[] line) {
93+
final var stack = new LinkedList<BracketType>();
94+
for (int i = 0; i < line.length; i++) {
95+
final var c = line[i];
96+
if (c == '(' || c == '[' || c == '{' || c == '<') {
97+
stack.push(BracketType.forOpen(c));
98+
} else if (c == ')' || c == ']' || c == '}' || c == '>') {
99+
if (stack.peek().close == c) {
100+
stack.pop();
101+
} else {
102+
throw new IllegalArgumentException("Corrupt: " + new String(line));
103+
}
104+
}
105+
}
106+
long result = 0;
107+
while (!stack.isEmpty()) {
108+
final var unclosed = stack.pop();
109+
result = result * 5 + unclosed.autocompletePoints;
110+
}
111+
return result;
112+
}
113+
114+
@Test
115+
public final void part1() {
116+
final var result = getInput()
117+
.map(String::toCharArray)
118+
.filter(line -> line.length > 0)
119+
.mapToInt(this::calculateCorruptionScore)
120+
.sum();
121+
System.out.println("Part 1: " + result);
122+
}
123+
124+
@Test
125+
public final void part2() {
126+
final var list = getInput()
127+
.map(String::toCharArray)
128+
.filter(line -> line.length > 0)
129+
.filter(line -> calculateCorruptionScore(line) <= 0) // discard corrupted lines
130+
.mapToLong(this::calculateCompletionScore)
131+
.sorted()
132+
.collect(ArrayList<Long>::new, List::add, List::addAll);
133+
final var result = list.get(list.size() / 2);
134+
System.out.println("Part 2: " + result);
135+
}
136+
137+
}

‎src/test/resources/sample/day-10.txt

Copy file name to clipboard
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[({(<(())[]>[[{[]{<()<>>
2+
[(()[<>])]({[<{<<[]>>(
3+
{([(<{}[<>[]}>{[]{[(<()>
4+
(((({<>}<{<{<>}{[]{[]{}
5+
[[<[([]))<([[{}[[()]]]
6+
[{[{({}]{}}([{[{{{}}([]
7+
{<[[]]>}<{[{[{[]{()[[[]
8+
[<(<(<(<{}))><([]([]()
9+
<{([([[(<>()){}]>(<<{{
10+
<{([{{}}[<[[[<>{}]]]>[]]

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.