Advertisement
Guest User

Day 20

a guest
Dec 20th, 2021
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.46 KB | None | 0 0
  1. """
  2. Advent of Code 2021 - Day 20
  3. https://adventofcode.com/2021/day/20
  4. """
  5.  
  6. from typing import List, Tuple
  7.  
  8. DAY = '20'
  9.  
  10. FULL_INPUT_FILE = f'../inputs/day{DAY}/input.full.txt'
  11. TEST_INPUT_FILE = f'../inputs/day{DAY}/input.test.txt'
  12.  
  13.  
  14. class Image:
  15.     def __init__(self, algorithm:str, image: List[str]) -> None:
  16.         self._algorithm_bitmap = [c == '#' for c in algorithm]
  17.         self._image_bitmap = [[c == '#' for c in r] for r in image]
  18.         self.background = False
  19.  
  20.     def add_margin(self, size: int = 1) -> None:
  21.         for row in self._image_bitmap:
  22.             row[0:0] = [self.background] * size
  23.             row[self.width:self.width] = [self.background] * size
  24.         self._image_bitmap[0:0] = [[self.background] * self.width] * size
  25.         self._image_bitmap[self.height:self.height] = [[self.background] * self.width] * size
  26.  
  27.     def crop(self) -> None:
  28.         while all(c == self.background for c in self._image_bitmap[0]):
  29.             del self._image_bitmap[0]
  30.         while all(c == self.background for c in self._image_bitmap[-1]):
  31.             del self._image_bitmap[-1]
  32.         while all(c == self.background for c in [r[0] for r in self._image_bitmap]):
  33.             for s in self._image_bitmap:
  34.                 del s[0]
  35.         while all(c == self.background for c in [r[-1] for r in self._image_bitmap]):
  36.             for s in self._image_bitmap:
  37.                 del s[-1]
  38.  
  39.     def enhance(self, steps: int = 1) -> None:
  40.         for _ in range(steps):
  41.             self.add_margin(2)
  42.             new_background = self._algorithm_bitmap[
  43.                 int(''.join([str(int(self.background))] * 9), 2)
  44.             ]
  45.  
  46.             new_bitmap = []
  47.             for i in range(self.height):
  48.                 new_bitmap.append([new_background] * self.width)
  49.  
  50.             for row_num in range(1, self.height - 1):
  51.                 for col_num in range(1, self.width - 1):
  52.                     n = [self._image_bitmap[row_num + i][col_num - 1:col_num + 2]
  53.                          for i in (-1, 0, 1)]
  54.                     n = int(''.join([str(int(bit)) for row in n for bit in row]), 2)
  55.                     new_bitmap[row_num][col_num] = self._algorithm_bitmap[n]
  56.             self._image_bitmap = new_bitmap
  57.             self.background = new_background
  58.             self.crop()
  59.  
  60.     @property
  61.     def width(self) -> int:
  62.         return len(self._image_bitmap[0])
  63.  
  64.     @property
  65.     def height(self) -> int:
  66.         return len(self._image_bitmap)
  67.  
  68.     @property
  69.     def rendered_image(self) -> str:
  70.         return '\n'.join([''.join(['#' if c else '.' for c in l]) for l in self._image_bitmap])
  71.  
  72.     @property
  73.     def pixel_count(self) -> int:
  74.         return sum([sum(r) for r in self._image_bitmap])
  75.  
  76.  
  77. def load_image(infile_path: str) -> Image:
  78.     with open(infile_path, 'r', encoding='ascii') as infile:
  79.         algorithm = infile.readline().strip()
  80.         infile.readline()
  81.         image = []
  82.         for line in infile:
  83.             image.append(line.strip())
  84.         return Image(algorithm, image)
  85.  
  86.  
  87. def part_1(infile_path: str) -> int:
  88.     img = load_image(infile_path)
  89.     img.enhance(2)
  90.     return img.pixel_count
  91.  
  92.  
  93. def part_2(infile_path: str) -> int:
  94.     img = load_image(infile_path)
  95.     img.enhance(50)
  96.     return img.pixel_count
  97.  
  98.  
  99. if __name__ == '__main__':
  100.     part1_answer = part_1(FULL_INPUT_FILE)
  101.     print(f'Part 1: {part1_answer}')
  102.  
  103.     part2_answer = part_2(FULL_INPUT_FILE)
  104.     print(f'Part 2: {part2_answer}')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement