Advertisement
Guest User

Advent of Code Day 24

a guest
Dec 24th, 2020
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.56 KB | None | 0 0
  1. """Day 24 of Advent of Code 2020 Solution"""
  2. from collections import defaultdict, Counter
  3. from itertools import chain
  4. import re
  5.  
  6.  
  7. class HexGrid:
  8.     directions = {
  9.         "ne": (1, 0, -1),
  10.         "e": (1, -1, 0),
  11.         "se": (0, -1, 1),
  12.         "sw": (-1, 0, 1),
  13.         "w": (-1, 1, 0),
  14.         "nw": (0, 1, -1),
  15.     }
  16.  
  17.     def __init__(self):
  18.         self.grid = defaultdict(bool)
  19.  
  20.     def add_tile(self, move):
  21.         x, y, z = 0, 0, 0
  22.         for d in move:
  23.             x += self.directions[d][0]
  24.             y += self.directions[d][1]
  25.             z += self.directions[d][2]
  26.         if (x, y, z) in self.grid:
  27.             self.flip_tile((x, y, z))
  28.         else:
  29.             self.grid[(x, y, z)] = True
  30.  
  31.     def flip_tile(self, location):
  32.         if self.grid[location]:
  33.             self.grid[location] = False
  34.         else:
  35.             self.grid[location] = True
  36.  
  37.     @property
  38.     def black(self):
  39.         return sum([*self.grid.values()])
  40.  
  41.     def __iter__(self):
  42.         return self
  43.  
  44.     def __next__(self):
  45.         grid = defaultdict(bool)
  46.         all_adj_tiles = []
  47.         for tile in self.grid:
  48.             if self.grid[tile]:
  49.                 adj_tiles = [
  50.                     tuple([_t + _d for _t, _d in zip(tile, d)])
  51.                     for d in self.directions.values()
  52.                 ]
  53.                 n_adjacent = sum([self.grid[t] for t in adj_tiles if t in self.grid])
  54.                 grid[tile] = True if 0 < n_adjacent <= 2 else False
  55.                 all_adj_tiles.append(adj_tiles)
  56.         adjacent_count = Counter([*chain.from_iterable(all_adj_tiles)])
  57.         for tile in adjacent_count:
  58.             if not self.grid[tile] and adjacent_count[tile] == 2:
  59.                 grid[tile] = True
  60.         self.grid = grid
  61.  
  62.  
  63. def directions_io(file_location):
  64.     pattern = r"(ne)|(e)|(se)|(sw)|(w)|(nw)"
  65.     directions = []
  66.     with open(file_location, "r") as f:
  67.         for line in f.readlines():
  68.             directions.append([l.group() for l in re.finditer(pattern, line)])
  69.     return directions
  70.  
  71.  
  72. def part_a(file_location):
  73.     directions = directions_io(file_location)
  74.     hex = HexGrid()
  75.     for d in directions:
  76.         hex.add_tile(d)
  77.     return hex.black
  78.  
  79.  
  80. def part_b(file_location):
  81.     directions = directions_io(file_location)
  82.     hex = HexGrid()
  83.     for d in directions:
  84.         hex.add_tile(d)
  85.     for _ in range(100):
  86.         next(hex)
  87.     return hex.black
  88.  
  89.  
  90. if __name__ == "__main__":
  91.     file_location = r"data\day24.txt"
  92.     print(part_a(file_location))
  93.     print(part_b(file_location))
  94.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement