The following code solves Advent Of Code 2021 Day 10.
The goal for this time around is evaluating whether a line of brackets is complete, has a syntax error or is missing some closing brackets.
Examples of valid pairs of brackets
()
[]
([])
{()()()}
<([{}])>
[<>({}){}[([])<>]]
(((((((((())))))))))
Example of incorrect or corrupted lines
{([(<{}[<>[]}>{[]{[(<()> # Expected ], but found } instead.
[[<[([]))<([[{}[[()]]] # Expected ], but found ) instead.
[{[{({}]{}}([{[{{{}}([] # Expected ), but found ] instead.
[<(<(<(<{}))><([]([]() # Expected >, but found ) instead.
<{([([[(<>()){}]>(<<{{ # Expected ], but found > instead.
Examples of incomplete lines
[({(<(())[]>[[{[]{<()<>> # Complete by adding }}]])})].
[(()[<>])]({[<{<<[]>>( # Complete by adding )}>]}).
(((({<>}<{<{<>}{[]{[]{} # Complete by adding }}>}>)))).
{<[[]]>}<{[{[{[]{()[[[] # Complete by adding ]]}}]}]}>.
<{([{{}}[<[[[<>{}]]]>[]] # Complete by adding ])}>.
Problem:
Advent of code 10 was divided into two problems:
- Find the sum of all lines that has a syntax error (
corrupted
), where every bracket that causes a syntax error is given a particular value. - Find each line that was
incomplete
, complete the line and find the autocomplete score of the completed portion. For every line in the test data, we were then asked to find the median of the autocomplete scores.
Code
from typing import Final
# Points for each illegal character
points: Final[dict[str, int]] = {
')': 3,
']': 57,
'}': 1197,
'>': 25137
}
# Bracket pairs
pairs: Final[dict[str, int]] = {
'(': ')',
'[': ']',
'{': '}',
'<': '>'
}
# Values for scoring completion characters
values: Final[dict[str, int]] = {
')': 1,
']': 2,
'}': 3,
'>': 4
}
def syntax_error_score_and_autocomplete_score(lines):
scores = []
total_score = 0
for line in lines:
stack = []
corrupted = False
corrupted_char = None
for char in line.strip():
if char in pairs:
# Opening bracket
stack.append(char)
else:
# Closing bracket
if not stack:
# Extra closing bracket, corrupted
corrupted = True
corrupted_char = char
break
top = stack.pop()
if pairs[top] != char:
# Mismatched closing bracket, corrupted
corrupted = True
corrupted_char = char
break
# Ignore corrupted lines
# If the line is corrupted, add the corresponding points
if corrupted:
total_score += points[corrupted_char]
continue
# If stack is not empty, we need to complete the line
if stack:
completion_string = ""
while stack:
opening = stack.pop()
completion_string += pairs[opening]
# Calculate score for this completion string
score = 0
for ch in completion_string:
score = score * 5 + values[ch]
scores.append(score)
print("part1: (syntax_error_score)", total_score)
scores.sort()
# Get the middle score
print("part2: (autocomplete_score)", scores[len(scores)//2])
if __name__ == "__main__":
with open("D:\\ExplorerDownload\\input2021_day10.txt", "r") as f:
lines = f.readlines()
syntax_error_score_and_autocomplete_score(lines)