My advent of code solutions
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

110 lines
2.9 KiB

"""
Advent of Code 2021 - Day 10
Run with:
python puzzles/day10.py inputs/day10.txt
"""
import pathlib
import sys
from typing import Dict, List, Tuple
from statistics import median
class Subsystem:
nav_data = None
open_chars = ["(", "[", "{", "<"]
close_chars = [")", "]", "}", ">"]
def __init__(self, inputs: List[str]) -> None:
self.nav_data = inputs
self.validate()
def validate(self) -> None:
chunks = {"corrupted": [], "incomplete": [], "complete": []}
corrupted_chars = []
incomplete_chunks = []
for line in self.nav_data:
corrupted = False
opens = []
for char in line:
if char in self.open_chars:
opens.append(char)
continue
open_char = self.open_chars[self.close_chars.index(char)]
if opens[-1] != open_char:
corrupted = True
corrupted_chars.append(char)
break
del opens[-1] # Clear the open bracket
if corrupted:
chunks["corrupted"].append(line)
elif len(opens) != 0:
chunks["incomplete"].append(line)
incomplete_chunks.append(opens)
else:
chunks["complete"].append(line)
self.chunks = chunks
self.corrupted_chars = corrupted_chars
self.incomplete_chunks = incomplete_chunks
def score_corrupted(self) -> int:
scores = {")": 3, "]": 57, "}": 1197, ">": 25137,}
return sum([scores[char] for char in self.corrupted_chars])
def score_incomplete(self) -> int:
scores = {")": 1, "]": 2, "}": 3, ">": 4,}
total_scores = []
for chunk in self.incomplete_chunks:
total_score = 0
for char in reversed(chunk):
close_char = self.close_chars[self.open_chars.index(char)]
total_score = total_score * 5 + scores[close_char]
total_scores.append(total_score)
return median(total_scores)
def part1(inputs: List[int]) -> int:
s = Subsystem(inputs)
return s.score_corrupted()
def part2(inputs: List[int]) -> int:
s = Subsystem(inputs)
return s.score_incomplete()
def parse(inputs: str) -> List[int]:
"""Parse the input string"""
return inputs.split()
def solve(path: str) -> Tuple[int, int]:
"""Solve the puzzle"""
puzzle_input = parse(pathlib.Path(path).read_text().strip())
part1_result = part1(puzzle_input)
part2_result = part2(puzzle_input)
return part1_result, part2_result
def main() -> None:
for path in sys.argv[1:]:
print(f"Input File: {path}")
part1_result, part2_result = solve(path)
print(f"Part 1 Result: {part1_result}")
print(f"Part 2 Result: {part2_result}")
if __name__ == "__main__":
main()