Solve 2021:10 "Syntax Scoring"
Spent over an hour trying to figure out the incomplete sequenses, only to realize it was easier to begin from the other way around. After that, solution came out nice and clean.
This commit is contained in:
parent
95c244102f
commit
801f977e92
2 changed files with 119 additions and 0 deletions
80
2021-python/solutions/day_10.py
Normal file
80
2021-python/solutions/day_10.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
from collections import deque
|
||||
from solutions import BaseSolution
|
||||
|
||||
|
||||
class Solution(BaseSolution):
|
||||
input_file = "10.txt"
|
||||
|
||||
def __str__(self):
|
||||
return "Day 10: Syntax Scoring"
|
||||
|
||||
def parse_input(self, data):
|
||||
return data.split()
|
||||
|
||||
def solve(self, puzzle_input):
|
||||
scores = {
|
||||
")": 3,
|
||||
"]": 57,
|
||||
"}": 1197,
|
||||
">": 25137,
|
||||
}
|
||||
co = {"]": "[", "}": "{", ">": "<", ")": "("}
|
||||
openers = co.values()
|
||||
closers = co.keys()
|
||||
|
||||
def corrupt(l):
|
||||
o = deque()
|
||||
for i, c in enumerate(l):
|
||||
if c in openers:
|
||||
o.append(c)
|
||||
continue
|
||||
if co[c] != o.pop():
|
||||
return i, c
|
||||
else:
|
||||
return 0
|
||||
|
||||
lines = list(filter(corrupt, puzzle_input))
|
||||
return sum(scores[c] for _, c in map(corrupt, lines))
|
||||
|
||||
def solve_again(self, puzzle_input):
|
||||
scoremap = {
|
||||
")": 1,
|
||||
"]": 2,
|
||||
"}": 3,
|
||||
">": 4,
|
||||
}
|
||||
co = {"]": "[", "}": "{", ">": "<", ")": "("}
|
||||
oc = dict([(o, c) for c, o in co.items()])
|
||||
openers = co.values()
|
||||
closers = co.keys()
|
||||
|
||||
def score(chars):
|
||||
s = 0
|
||||
for i, x in enumerate(chars):
|
||||
s *= 5
|
||||
s += scoremap[x]
|
||||
return s
|
||||
|
||||
def incomplete(l):
|
||||
o = deque()
|
||||
for c in l:
|
||||
if c in openers:
|
||||
o.append(c)
|
||||
continue
|
||||
if co[c] != o.pop():
|
||||
return 0
|
||||
else:
|
||||
return o
|
||||
|
||||
lines = list(filter(incomplete, puzzle_input))
|
||||
med = len(lines) // 2
|
||||
completes = [
|
||||
score([oc[oo] for oo in reversed(o)]) for o in map(incomplete, lines)
|
||||
]
|
||||
return sorted(completes)[med]
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
solution = Solution()
|
||||
solution.show_results()
|
||||
39
2021-python/tests/test_day_10.py
Normal file
39
2021-python/tests/test_day_10.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import unittest
|
||||
|
||||
from solutions.day_10 import Solution
|
||||
|
||||
|
||||
class Day10TestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.solution = Solution()
|
||||
self.puzzle_input = self.solution.parse_input(
|
||||
"""
|
||||
[({(<(())[]>[[{[]{<()<>>
|
||||
[(()[<>])]({[<{<<[]>>(
|
||||
{([(<{}[<>[]}>{[]{[(<()>
|
||||
(((({<>}<{<{<>}{[]{[]{}
|
||||
[[<[([]))<([[{}[[()]]]
|
||||
[{[{({}]{}}([{[{{{}}([]
|
||||
{<[[]]>}<{[{[{[]{()[[[]
|
||||
[<(<(<(<{}))><([]([]()
|
||||
<{([([[(<>()){}]>(<<{{
|
||||
<{([{{}}[<[[[<>{}]]]>[]]
|
||||
"""
|
||||
)
|
||||
|
||||
def test_parse_puzzle_input(self):
|
||||
data = """
|
||||
abc
|
||||
efg
|
||||
"""
|
||||
assert self.solution.parse_input(data) == ["abc", "efg"]
|
||||
|
||||
def test_solve_first_part(self):
|
||||
assert self.solution.solve(self.puzzle_input) == 26397
|
||||
|
||||
def test_solve_second_part(self):
|
||||
assert self.solution.solve_again(self.puzzle_input) == 288957
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Reference in a new issue