Advertisement
Guest User

Advent of Code Day 17

a guest
Dec 17th, 2020
333
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.31 KB | None | 0 0
  1. """Day 17 of Advent of Code 2020 Solution"""
  2. from collections import Counter
  3. from itertools import chain, product
  4.  
  5.  
  6. def get_adjacent(point):
  7.     """Yield tuples with values+-1 for each value in input point"""
  8.     for adj in product(*[[i + n for n in (-1, 0, 1)] for i in point]):
  9.         yield adj
  10.  
  11.  
  12. class ConwayCube:
  13.     static = {2, 3}
  14.     activator = 3
  15.  
  16.     def __init__(self, start_position: list[str], dimension: int = 3):
  17.         self.active_points: set[tuple[int, ...]] = set()
  18.         self.dimension: int = dimension - 2
  19.  
  20.         for y, row in enumerate(start_position):
  21.             for x, col in enumerate(row):
  22.                 if start_position[y][x] == "#":
  23.                     self.active_points.add(tuple([x, y] + [0] * self.dimension))
  24.  
  25.     def __iter__(self):
  26.         return self
  27.  
  28.     def __next__(self):
  29.         next_active = set()
  30.         adjacent_points = []
  31.         for p in self.active_points:
  32.             p_adjacent = [adj for adj in get_adjacent(p) if adj != p]
  33.             adjacent_points.append(p_adjacent)
  34.             n_adjacent = 0
  35.             for a in p_adjacent:
  36.                 if a in self.active_points:
  37.                     n_adjacent += 1
  38.             if n_adjacent in self.static:
  39.                 next_active.add(p)
  40.  
  41.         adjacent_points = [*chain.from_iterable(adjacent_points)]
  42.         adjacent_count = Counter(adjacent_points)
  43.  
  44.         for p in adjacent_count:
  45.             if p in self.active_points:
  46.                 pass
  47.             else:
  48.                 if adjacent_count[p] == self.activator:
  49.                     next_active.add(p)
  50.         self.active_points = next_active
  51.  
  52.     @property
  53.     def active(self) -> int:
  54.         return len(self.active_points)
  55.  
  56.  
  57. def cycle_cubes(file_location, dimensions=3, n_cycles=6) -> int:
  58.     with open(file_location, "r") as f:
  59.         data = [line.strip() for line in f.readlines()]
  60.     cc = ConwayCube(data, dimensions)
  61.     for _ in range(n_cycles):
  62.         next(cc)
  63.     return cc.active
  64.  
  65.  
  66. def part_a(file_location):
  67.     return cycle_cubes(file_location, dimensions=3, n_cycles=6)
  68.  
  69.  
  70. def part_b(file_location):
  71.     return cycle_cubes(file_location, dimensions=4, n_cycles=6)
  72.  
  73.  
  74. if __name__ == "__main__":
  75.     file_location = r"data\day17.txt"
  76.     print(part_a(file_location))
  77.     print(part_b(file_location))
  78.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement