123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- import numpy as np
-
- with open('data/21.txt') as file:
- mappings = dict()
- for line in file.readlines():
- parts = tuple(map(lambda p: np.array(list(map(lambda r: [c == '#' for c in r], p.split('/')))),
- line.strip().split(' => ')))
-
- # All possible transformations of our mappings:
- # - 0, 90, 180 and 270 degree rotations
- # - vertical (up<>down) flip followed by the 4 rotations
- # - horizontal (left<>right) flip followed by the 4 rotations
- # ...Some of these may be equivalent...
- keys = [
- *(np.rot90(parts[0], k) for k in range(3)),
- *(np.rot90(np.flipud(parts[0]), k) for k in range(3)),
- *(np.rot90(np.fliplr(parts[0]), k) for k in range(3)),
- ]
-
- for key in keys:
- mappings[key.tobytes()] = parts[1]
-
-
- def expand(old_grid, length, oss, nss):
- """
- Expands a grid by replacing all segments with their mapped versions.
-
- :param old_grid: The grid to expand
- :param length: The current size of the grid (length in any direction)
- :param oss: The size of the segment to be replaced (old segment size)
- :param nss: The size of the segment that will replace it (new segment size)
- :return: A new grid, with each segment expanded
- """
- new_grid = np.empty((length // oss * nss, length // oss * nss), dtype=bool)
- for x in range(0, length, oss):
- for y in range(0, length, oss):
- new_x = x // oss * nss
- new_y = y // oss * nss
- new_grid[new_x:new_x+nss, new_y:new_y+nss] = mappings[old_grid[x:x + oss, y:y + oss].tobytes()]
- return new_grid
-
-
- grid = np.array([[False, True, False], [False, False, True], [True, True, True]])
- for i in range(18):
- size = len(grid)
- grid = expand(grid, size, 2, 3) if size % 2 == 0 else expand(grid, size, 3, 4)
-
- if i == 4:
- print(f'Part one: {sum(sum(grid))}')
- elif i == 17:
- print(f'Part two: {sum(sum(grid))}')
|