Advertisement
Guest User

AoC 2021 - Day 22

a guest
Dec 22nd, 2021
1,320
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.38 KB | None | 0 0
  1. """
  2. Advent of Code 2021 - Day 22
  3. https://adventofcode.com/2021/day/22
  4. """
  5.  
  6. import re
  7. from typing import List, Tuple, Union, Any
  8.  
  9. DAY = '22'
  10.  
  11. FULL_INPUT_FILE = f'../inputs/day{DAY}/input.full.txt'
  12. TEST_INPUT_FILE_1 = f'../inputs/day{DAY}/input.test1.txt'
  13. TEST_INPUT_FILE_2 = f'../inputs/day{DAY}/input.test2.txt'
  14. TEST_INPUT_FILE_3 = f'../inputs/day{DAY}/input.test3.txt'
  15.  
  16.  
  17. def load_data(infile_path: str) -> List[List[Union[str, Any]]]:
  18.     data = []
  19.     with open(infile_path, 'r', encoding='ascii') as infile:
  20.         for line in infile:
  21.             split_data = \
  22.                 re.match(r'(\w+) x=(-?\d+)\.\.(-?\d+),y=(-?\d+)\.\.(-?\d+),z=(-?\d+)\.\.(-?\d+)$',
  23.                          line).groups()
  24.             data.append([split_data[0]] + [int(i) for i in split_data[1:]])
  25.     return data
  26.  
  27.  
  28. def overlapping_box(box_a: List[int], box_b: List[int]) -> Tuple[int, ...]:
  29.     max_x, max_y, max_z = [max(box_a[i], box_b[i]) for i in (0, 2, 4)]
  30.     min_xp, min_yp, min_zp = [min(box_a[i], box_b[i]) for i in (1, 3, 5)]
  31.     if min_xp - max_x >= 0 and min_yp - max_y >= 0 and min_zp - max_z >= 0:
  32.         return max_x, min_xp, max_y,  min_yp, max_z, min_zp
  33.  
  34.  
  35. def count_lit_cubes(data):
  36.     lit_count = 0
  37.     counted_zones = []
  38.     for d in reversed(data):
  39.         mode, box = d[0], d[1:]
  40.         x1, x2, y1, y2, z1, z2 = box
  41.         if mode == 'on':
  42.             dead_cubes = []
  43.             for overlap_box in [overlapping_box(zone, box) for zone in counted_zones]:
  44.                 if overlap_box:
  45.                     dead_cubes.append(('on', *overlap_box))
  46.             lit_count += (x2 - x1 + 1) * (y2 - y1 + 1) * (z2 - z1 + 1)
  47.             lit_count -= count_lit_cubes(dead_cubes)
  48.         counted_zones.append(box)
  49.     return lit_count
  50.  
  51.  
  52. def part_1(infile_path:str) -> int:
  53.     data = []
  54.     for row in load_data(infile_path):
  55.         x1, x2, y1, y2, z1, z2 = row[1:]
  56.         if x1 <= 50 and x2 >= -50 and y1 <= 50 and y2 >= -50 and z1 <= 50 and z2 >= -50:
  57.             data.append(row)
  58.     lit_count = count_lit_cubes(data)
  59.     return lit_count
  60.  
  61.  
  62. def part_2(infile_path: str) -> int:
  63.     data = load_data(infile_path)
  64.     lit_count = count_lit_cubes(data)
  65.     return lit_count
  66.  
  67.  
  68. if __name__ == '__main__':
  69.     part1_answer = part_1(FULL_INPUT_FILE)
  70.     print(f'Part 1: {part1_answer}')
  71.  
  72.     part2_answer = part_2(FULL_INPUT_FILE)
  73.     print(f'Part 2: {part2_answer}')
  74.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement