Advertisement
JonathanGupton

Advent of Code 2022 - Day 13 - Python

Dec 13th, 2022
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.75 KB | None | 0 0
  1. from ast import literal_eval
  2. from functools import cmp_to_key
  3. from itertools import zip_longest
  4. from typing import Optional, Iterable, Union
  5. from enum import IntEnum
  6.  
  7.  
  8. DistressSignal = Optional[Union[Iterable, int]]
  9.  
  10.  
  11. class Result(IntEnum):
  12.     Ordered = -1
  13.     Unordered = 0
  14.     Undetermined = 1
  15.  
  16.  
  17. def parse_distress_signal(filepath) -> DistressSignal:
  18.     distress_signals = []
  19.     with open(filepath, "r") as f:
  20.         for chunk in f.read().split("\n\n"):
  21.             lhs, rhs = chunk.split("\n")
  22.             distress_signals.append([literal_eval(lhs), literal_eval(rhs)])
  23.     return distress_signals
  24.  
  25.  
  26. def flatten_distress_signals(signals) -> list[DistressSignal]:
  27.     flattened = []
  28.     for pair in signals:
  29.         flattened.extend(pair)
  30.     return flattened
  31.  
  32.  
  33. def analyze_signal(signal: DistressSignal) -> Result:
  34.     for (lhs, rhs) in zip_longest(*signal):
  35.         match (lhs, rhs):
  36.             case (list(), list()):
  37.                 if (result := analyze_signal((lhs, rhs))) is Result.Undetermined:
  38.                     continue
  39.                 else:
  40.                     return result
  41.  
  42.             case (int(), list()):
  43.                 if (result := analyze_signal(([lhs], rhs))) is Result.Undetermined:
  44.                     continue
  45.                 else:
  46.                     return result
  47.  
  48.             case (list(), int()):
  49.                 if (result := analyze_signal((lhs, [rhs]))) is Result.Undetermined:
  50.                     continue
  51.                 else:
  52.                     return result
  53.  
  54.             case (int(), int()):
  55.                 if lhs < rhs:
  56.                     return Result.Ordered
  57.                 elif lhs == rhs:
  58.                     continue
  59.                 elif lhs > rhs:
  60.                     return Result.Unordered
  61.  
  62.             case (int(), None) | (list(), None):
  63.                 return Result.Unordered
  64.  
  65.             case (None, int()) | (None, list()):
  66.                 return Result.Ordered
  67.  
  68.             case (None, None):
  69.                 return Result.Undetermined
  70.  
  71.             case _:
  72.                 raise Exception("What the hell am I doin' here?\nI don't belong here?")
  73.  
  74.     return Result.Undetermined
  75.  
  76.  
  77. def part_one(filepath) -> int:
  78.     signal = parse_distress_signal(filepath)
  79.     total = 0
  80.     for i, pair in enumerate(signal, 1):
  81.         if analyze_signal(pair) is Result.Ordered:
  82.             total += i
  83.     return total
  84.  
  85.  
  86. def part_two(filepath) -> int:
  87.     signals = parse_distress_signal(filepath)
  88.     flattened_signal = flatten_distress_signals(signals)
  89.     divs = [[[2]], [[6]]]
  90.     flattened_signal.extend(divs)
  91.     flattened_signal.sort(key=cmp_to_key(lambda x, y: analyze_signal((x, y))))
  92.     return (flattened_signal.index(divs[0]) + 1) * (flattened_signal.index(divs[1]) + 1)
  93.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement