Advertisement
Guest User

AoC 2022 Day 13

a guest
Jan 12th, 2023
1,377
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.98 KB | None | 0 0
  1. # aoc202213.py
  2.  
  3. import json
  4. import pathlib
  5. import sys
  6.  
  7.  
  8. def parse(puzzle_input: str) -> list[list[int, ...]]:
  9.     """Convert str representations of lists into real int lists"""
  10.     str_pkts: list[list[str, str]] = [
  11.         packet.splitlines() for packet in puzzle_input.split("\n\n")
  12.     ]
  13.     int_pkts: list[list[int, ...]] = []
  14.     for pkt in str_pkts:
  15.         int_pk: list[int, ...] = []
  16.         for pk in pkt:
  17.             # Here's the magick - I'm highly averse to eval()
  18.             int_pk.append(json.loads(pk))
  19.         int_pkts.append(int_pk)
  20.     return int_pkts
  21.  
  22.  
  23. def compare(l: int, r: int) -> int:
  24.     """Compare 2 ints, return 1, 0, -1 depending on values"""
  25.     if l < r:
  26.         return 1
  27.     elif l > r:
  28.         return -1
  29.     else:
  30.         return 0
  31.  
  32.  
  33. def compare_packets(left: list[int, ...], right: list[int, ...]) -> int:
  34.     """Compare 2 lists to establish correct order"""
  35.     match left, right:
  36.         case int(), int():
  37.             return compare(left, right)
  38.         case int(), list():
  39.             return compare_packets([left], right)
  40.         case list(), int():
  41.             return compare_packets(left, [right])
  42.         case list(), list():
  43.             for l, r in zip(left, right):
  44.                 res = compare_packets(l, r)
  45.                 if res != 0:
  46.                     return res
  47.             return compare_packets(len(left), len(right))
  48.  
  49.  
  50. def part1(pairs: list[list[int, ...]]) -> int:
  51.     """Solve part 1"""
  52.     sum_of_indices: int = 0
  53.     for idx, pair in enumerate(pairs):
  54.         if compare_packets(*pair) == 1:
  55.             sum_of_indices += idx + 1
  56.     return sum_of_indices
  57.  
  58.  
  59. def flatten(l: list[list[int]]) -> list[int]:
  60.     """Flatten a nested list one level"""
  61.     return [item for sublist in l for item in sublist]
  62.  
  63.  
  64. def find_index(l: list[list[int]], item: list[int]) -> int:
  65.     """Return index of where item falls in list"""
  66.     item_idx: int = 0
  67.     for pkt in flatten(l):
  68.         if compare_packets(pkt, item) == 1:
  69.             item_idx += 1
  70.     return item_idx
  71.  
  72.  
  73. def part2(pairs: list[list[int, ...]]) -> int:
  74.     """Solve part 2"""
  75.     # Remove one layer of list to match flattened list above
  76.     first_divider: list[int] = [2]
  77.     second_divider: list[int] = [6]
  78.  
  79.     first_pos: int = find_index(pairs, first_divider) + 1
  80.     second_pos: int = find_index(pairs, second_divider) + 2
  81.     return first_pos * second_pos
  82.  
  83.  
  84. def solve(puzzle_input: str) -> tuple[int, int]:
  85.     """Solve the puzzle for the given input"""
  86.     data: list[list[int, ...]] = parse(puzzle_input)
  87.     solution1: int = part1(data)  # Correct answer was 4734 (with my data)
  88.     solution2: int = part2(data)  # Correct answer was 21836 (with my data)
  89.  
  90.     return solution1, solution2
  91.  
  92.  
  93. if __name__ == "__main__":
  94.     for path in sys.argv[1:]:
  95.         print(f"{path}:")
  96.         puzzle_input = pathlib.Path(path).read_text().strip()
  97.         solutions = solve(puzzle_input)
  98.         print("\n".join(str(solution) for solution in solutions))
  99.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement