Advertisement
Guest User

AOC 2021 Day 10

a guest
Dec 14th, 2021
567
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.21 KB | None | 0 0
  1. # aoc202110.py
  2.  
  3. import pathlib
  4. import sys
  5.  
  6. openings = '{([<'
  7. closings = '})]>'
  8.  
  9. closing_brackets = {cl: op for op, cl in zip(openings, closings)}
  10. opening_brackets = {op: cl for op, cl in zip(openings, closings)}
  11.  
  12. syntax_error_scores = {')': 3, ']': 57, '}': 1197, '>': 25137}
  13. autocomplete_scores = {')': 1, ']': 2, '}': 3, '>': 4}
  14.  
  15.  
  16. def parse(puzzle_input: str) -> list[int]:
  17.     """ Parse input """
  18.     return puzzle_input.splitlines()
  19.  
  20.  
  21. def find_mismatch(text: str) -> str:
  22.     """ Go thru a string and see if there's a mismatch """
  23.     stack = []
  24.     for char in text:
  25.         if char in openings:
  26.             stack.append(char)
  27.         elif char in closings:
  28.             popped = stack.pop()
  29.             if closing_brackets[char] != popped:
  30.                 # print(
  31.                 #     f"Expected {opening_brackets[popped]}, but found {char} instead."
  32.                 # )
  33.                 return char
  34.  
  35.  
  36. def part1(navi_sub: list[int]) -> int:
  37.     """ Solve part 1 """
  38.     scores = []
  39.     for line in navi_sub:
  40.         incorrect_char = find_mismatch(line)
  41.         if incorrect_char is not None:
  42.             scores.append(syntax_error_scores[incorrect_char])
  43.     return sum(scores)
  44.  
  45.  
  46. def remove_corrupted(lines: list[str]) -> list[str]:
  47.     """ Return a list of only incomplete lines """
  48.     incompletes = []
  49.     for line in lines:
  50.         if find_mismatch(line):
  51.             continue
  52.         incompletes.append(line)
  53.     return incompletes
  54.  
  55.  
  56. def fill_stack(line: str) -> list[str]:
  57.     """ Fill the tack with chars from line and see what's left """
  58.     stack = []
  59.     for char in line:
  60.         if char in openings:
  61.             stack.append(char)
  62.         elif char in closings:
  63.             stack.pop()
  64.     return stack
  65.  
  66.  
  67. def get_missing(line: str) -> list[str]:
  68.     """ See contents of stack and generate missing closings """
  69.     # Return contents of stack (unclaimed openings)
  70.     leftovers = fill_stack(line)
  71.     # Get a list of the endings
  72.     return [opening_brackets[op] for op in leftovers[::-1]]
  73.  
  74.  
  75. def autocomplete_score(chars: list[str]) -> int:
  76.     """ Check the chars left in the Stack and calculate the score """
  77.     score = 0
  78.     for char in chars:
  79.         score *= 5
  80.         score += autocomplete_scores[char]
  81.     return score
  82.  
  83.  
  84. def part2(navi_sub: list[int]) -> int:
  85.     """ Solve part 2 """
  86.     incompletes = remove_corrupted(navi_sub)
  87.     scores = []
  88.     for line in incompletes:
  89.         missing_chars = get_missing(line)
  90.         scores.append(autocomplete_score(missing_chars))
  91.     # Return "middle" value
  92.     low_high = sorted(scores)
  93.     mid_idx = len(low_high) // 2
  94.     return low_high[mid_idx]
  95.  
  96.  
  97. def solve(puzzle_input: str) -> tuple[int, int]:
  98.     """ Solve the puzzle for the given input """
  99.     data = parse(puzzle_input)
  100.     solution1 = part1(data)  # Correct answer was 469755 (with my data)
  101.     solution2 = part2(data)  # Correct answer was 2762335572 (with my data)
  102.  
  103.     return solution1, solution2
  104.  
  105.  
  106. if __name__ == "__main__":
  107.     for path in sys.argv[1:]:
  108.         print(f"{path}:")
  109.         puzzle_input = pathlib.Path(path).read_text().strip()
  110.         solutions = solve(puzzle_input)
  111.         print('\n'.join(str(solution) for solution in solutions))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement