Advertisement
Guest User

Advent of Code 2020 Day 11 trash fire

a guest
Dec 11th, 2020
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.79 KB | None | 0 0
  1. """Day 11 of Advent of Code 2020 Solution"""
  2. from typing import Union
  3.  
  4.  
  5. SeatingChart = dict[complex, str]
  6.  
  7.  
  8. def seating_io(file_location):
  9.     with open(file_location, "r") as f:
  10.         data = [list(line.strip()) for line in f.readlines()]
  11.         return data
  12.  
  13.  
  14. class SeatingSystem:
  15.     """
  16.    . - Floor
  17.    L - Empty seat
  18.    # - Occupied seat
  19.    """
  20.  
  21.     adjacency = [
  22.         complex(i, j)
  23.         for i in range(-1, 2)
  24.         for j in range(-1, 2)
  25.         if not all([i == 0, j == 0])
  26.     ]
  27.  
  28.     def __init__(self, seating_area):
  29.         self.seating_area: SeatingChart = {}
  30.         for i, row in enumerate(seating_area):
  31.             for j, seat in enumerate(row):
  32.                 self.seating_area[complex(i, j)] = seat
  33.         self.prior = None
  34.         self.current = self.seating_area.copy()
  35.  
  36.     def __next__(self):
  37.         self.prior = self.current.copy()
  38.         self.current.clear()
  39.         for seat in self.prior:
  40.             self.current[seat] = self.next_seat_position(seat)
  41.  
  42.     def next_seat_position(self, seat):
  43.         if self.prior[seat] == ".":
  44.             return "."
  45.         if self.prior[seat] == "#":
  46.             n_occupied = 0
  47.             for adj in self.adjacency:
  48.                 if self.prior.get(seat + adj, "L") == "#":
  49.                     n_occupied += 1
  50.             if n_occupied >= 4:
  51.                 return "L"
  52.             else:
  53.                 return "#"
  54.         if self.prior[seat] == "L":
  55.             for adj in self.adjacency:
  56.                 if self.prior.get(seat + adj, "L") == "#":
  57.                     return "L"
  58.             return "#"
  59.  
  60.     def __str__(self):
  61.         return str(self.current)
  62.  
  63.     def __eq__(self, other):
  64.         return self.current == other
  65.  
  66.     def __repr__(self):
  67.         return str(self)
  68.  
  69.     @property
  70.     def occupied(self):
  71.         return len([val for val in self.current.values() if val == "#"])
  72.  
  73.     @classmethod
  74.     def from_file(cls, file_location):
  75.         with open(file_location, "r") as f:
  76.             data = [list(line.strip()) for line in f.readlines()]
  77.             return cls(data)
  78.  
  79.  
  80. class SeatingSystemAdvanced(SeatingSystem):
  81.     """
  82.    . - Floor
  83.    L - Empty seat
  84.    # - Occupied seat
  85.    """
  86.  
  87.     adjacency = [
  88.         complex(i, j)
  89.         for i in range(-1, 2)
  90.         for j in range(-1, 2)
  91.         if not all([i == 0, j == 0])
  92.     ]
  93.  
  94.     def __next__(self):
  95.         self.prior = self.current.copy()
  96.         self.current.clear()
  97.         for seat in self.prior:
  98.             self.current[seat] = self.next_seat_position(seat)
  99.  
  100.     def next_seat_position(self, seat):
  101.         if self.prior[seat] == ".":
  102.             return "."
  103.         if self.prior[seat] == "#":
  104.             n_occupied = 0
  105.             for adj in self.adjacency:
  106.                 if self._get_dist_val(seat, adj) == "#":
  107.                     n_occupied += 1
  108.                     if n_occupied >= 5:
  109.                         return "L"
  110.             return "#"
  111.         if self.prior[seat] == "L":
  112.             for adj in self.adjacency:
  113.                 if self._get_dist_val(seat, adj) == "#":
  114.                     return "L"
  115.             return "#"
  116.  
  117.     def _get_dist_val(self, seat, direction):
  118.         n = 1
  119.         while self.prior.get(seat + direction * n, "L") == ".":
  120.             n += 1
  121.         return self.prior.get(seat + direction * n, "L")
  122.  
  123.  
  124.  
  125. def part_a(file_location):
  126.     ss = SeatingSystem.from_file(file_location)
  127.     while ss.prior != ss.current:
  128.         next(ss)
  129.     return ss.occupied
  130.  
  131.  
  132. def part_b(file_location):
  133.     ss = SeatingSystemAdvanced.from_file(file_location)
  134.     while ss.prior != ss.current:
  135.         next(ss)
  136.     return ss.occupied
  137.  
  138.  
  139. if __name__ == "__main__":
  140.     file_location = r"data\day11.txt"
  141.     print(part_a(file_location))
  142.     print(part_b(file_location))
  143.  
  144.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement