Advertisement
Guest User

Advent of Code 2021 Day 20

a guest
Dec 20th, 2021
777
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.59 KB | None | 0 0
  1. from itertools import product
  2. from typing import Generator
  3.  
  4.  
  5. def parse_input(filepath):
  6.     with open(filepath, "r") as f:
  7.         algorithm, image = f.read().split("\n\n")
  8.         image_map = {}
  9.         for y, row in enumerate(image.split("\n")):
  10.             for x, col in enumerate(row):
  11.                 image_map[complex(x, y)] = col
  12.     return algorithm, image_map
  13.  
  14.  
  15. def binary_to_dec(bin_number):
  16.     return int(bin_number, 2)
  17.  
  18.  
  19. def str_to_bin(arr: list[str]) -> list[str]:
  20.     return ["0" if i == "." else "1" for i in arr]
  21.  
  22.  
  23. def get_edges(image_map: dict[complex, str]) -> tuple[int, ...]:
  24.     x_min, y_min, x_max, y_max = (
  25.         float("inf"),
  26.         float("inf"),
  27.         float("-inf"),
  28.         float("-inf"),
  29.     )
  30.     for position in image_map:
  31.         x = position.real
  32.         y = position.imag
  33.         if x < x_min:
  34.             x_min = x
  35.         if y < y_min:
  36.             y_min = y
  37.         if x > x_max:
  38.             x_max = x
  39.         if y > y_max:
  40.             y_max = y
  41.     return tuple(map(int, (x_min, y_min, x_max, y_max)))
  42.  
  43.  
  44. def get_adjacent(
  45.     coordinate: complex,
  46.     window=(
  47.         complex(-1, -1),
  48.         complex(0, -1),
  49.         complex(1, -1),
  50.         complex(-1, 0),
  51.         complex(0, 0),
  52.         complex(1, 0),
  53.         complex(-1, 1),
  54.         complex(0, 1),
  55.         complex(1, 1),
  56.     ),
  57. ) -> Generator[complex, None, None]:
  58.     for adjacent in window:
  59.         yield coordinate + adjacent
  60.  
  61.  
  62. def process_image(image, algorithm, nth_iteration=None):
  63.     edges = get_edges(image)
  64.     if nth_iteration:
  65.         default = "#" if nth_iteration % 2 != 0 else "."
  66.     else:
  67.         default = "."
  68.     new_map = {}
  69.     for x, y in product(
  70.         range(edges[0] - 1, edges[2] + 2), range(edges[1] - 1, edges[3] + 2)
  71.     ):
  72.         next_num = [image.get(coord, default) for coord in get_adjacent(complex(x, y))]
  73.         next_num_bin = "".join(str_to_bin(next_num))
  74.         algo_idx_int = binary_to_dec(next_num_bin)
  75.         new_map[complex(x, y)] = algorithm[algo_idx_int]
  76.     return new_map
  77.  
  78.  
  79. def sum_image(img) -> int:
  80.     n = 0
  81.     for val in img.values():
  82.         if val == "#":
  83.             n += 1
  84.     return n
  85.  
  86.  
  87. def part_a():
  88.     fp = r"data/day20.txt"
  89.     algo, img = parse_input(fp)
  90.  
  91.     for i in range(2):
  92.         img = process_image(img, algo, i)
  93.     return sum_image(img)
  94.  
  95.  
  96. def part_b():
  97.     fp = r"data/day20.txt"
  98.     algo, img = parse_input(fp)
  99.  
  100.     for i in range(50):
  101.         img = process_image(img, algo, i)
  102.     return sum_image(img)
  103.  
  104.  
  105. if __name__ == "__main__":
  106.     print(part_a())
  107.     print(part_b())
  108.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement