-
Notifications
You must be signed in to change notification settings - Fork 3
/
day21.py
62 lines (47 loc) · 1.57 KB
/
day21.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import numpy as np
with open('./inputs/21.txt') as f:
instructions = f.readlines()
mappings = {}
start = '.#./..#/###'
def translate_to_np(s):
return np.array([[c == '#' for c in l]
for l in s.split('/')])
for line in instructions:
k, v = map(translate_to_np, line.strip().split(' => '))
for a in (k, np.fliplr(k)):
for r in range(4):
mappings[np.rot90(a, r).tobytes()] = v
def find_next(grid):
size = len(grid)
by = 2 if size % 2 == 0 else 3
new_size = size * (by+1) // by
new_grid = np.empty((new_size, new_size), dtype=bool)
squares = range(0, size, by)
new_squares = range(0, new_size, by+1)
for i, ni in zip(squares, new_squares):
for j, nj in zip(squares, new_squares):
square = grid[i:i+by, j:j+by]
enhanced = mappings[square.tobytes()]
new_grid[ni:ni+by+1, nj:nj+by+1] = enhanced
return new_grid
grid = translate_to_np(start)
for _ in range(5):
grid = find_next(grid)
print(grid.sum())
seen = {}
def find_new_9x9(grid):
gtb = grid.tobytes()
if gtb not in seen:
for _ in range(3):
grid = find_next(grid)
seen[gtb] = grid
return seen[gtb]
grid = find_next(grid) # 6th iteration -> 27x27 grid of independent 3x3's
for _ in range((18 - 6) // 3):
size = len(grid)
solution = np.empty((3*size, 3*size), dtype=bool)
for i in range(0, size, 3):
for j in range(0, size, 3):
solution[3*i:3*(i+3), 3*j:3*(j+3)] = find_new_9x9(grid[i:i+3, j:j+3])
grid = solution
print(grid.sum())