-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathday17.py
executable file
·126 lines (97 loc) · 2.83 KB
/
day17.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env python3
from utils.all import *
advent.setup(2020, 17)
fin = advent.get_input()
TESTPLZ = any(a.lower() == 'test' for a in sys.argv[1:])
ftest = io.StringIO('''\
.#.
..#
###
''')
if TESTPLZ:
fin = ftest
timer_start()
startgrid = read_char_matrix(fin)
cube = defaultdict(lambda: '.')
for x, row in enumerate(startgrid):
for y, cell in enumerate(row):
cube[x, y, 0] = cell
def neigh(cube, x, y, z):
tot = 0
for dx, dy, dz in product((-1, 0, 1), (-1, 0, 1), (-1, 0, 1)):
if dx != 0 or dy != 0 or dz != 0:
xx, yy, zz = (x + dx, y + dy, z + dz)
if cube[xx, yy, zz] == '#':
tot += 1
return tot
def evolve(cube):
new = deepcopy(cube)
lox = min(map(itemgetter(0), cube.keys())) - 1
loy = min(map(itemgetter(1), cube.keys())) - 1
loz = min(map(itemgetter(2), cube.keys())) - 1
hix = max(map(itemgetter(0), cube.keys())) + 2
hiy = max(map(itemgetter(1), cube.keys())) + 2
hiz = max(map(itemgetter(2), cube.keys())) + 2
for x, y, z in product(range(lox, hix), range(loy, hiy), range(loz, hiz)):
cell = cube[x, y, z]
alive = neigh(cube, x, y, z)
if cell == '#':
if alive not in (2, 3):
new[x, y, z] = '.'
elif cell == '.':
if alive == 3:
new[x, y, z] = '#'
return new
def dump(cube):
eprint()
grids = {}
for (x, y, z), cell in cube.items():
if z not in grids:
grids[z] = [['.' for _ in range(10)] for __ in range(10)]
grids[z][x][y] = cell
for z in grids:
eprint(f'z={z}')
dump_char_matrix(grids[z])
eprint()
for _ in range(6):
# dump(cube)
cube = evolve(cube)
# dump(cube)
ans = sum(x == '#' for x in cube.values())
advent.print_answer(1, ans)
def neigh4d(cube, x, y, z, w):
tot = 0
for dx, dy, dz, dw in product((-1, 0, 1), (-1, 0, 1), (-1, 0, 1), (-1, 0, 1)):
if dx != 0 or dy != 0 or dz != 0 or dw != 0:
xx, yy, zz, ww = (x + dx, y + dy, z + dz, w + dw)
if cube[xx, yy, zz, ww] == '#':
tot += 1
return tot
def evolve4d(cube):
new = deepcopy(cube)
lox = min(map(itemgetter(0), cube.keys())) - 1
loy = min(map(itemgetter(1), cube.keys())) - 1
loz = min(map(itemgetter(2), cube.keys())) - 1
low = min(map(itemgetter(3), cube.keys())) - 1
hix = max(map(itemgetter(0), cube.keys())) + 2
hiy = max(map(itemgetter(1), cube.keys())) + 2
hiz = max(map(itemgetter(2), cube.keys())) + 2
hiw = max(map(itemgetter(3), cube.keys())) + 2
for x, y, z, w in product(range(lox, hix), range(loy, hiy), range(loz, hiz), range(low, hiw)):
cell = cube[x, y, z, w]
alive = neigh4d(cube, x, y, z, w)
if cell == '#':
if alive not in (2, 3):
new[x, y, z, w] = '.'
elif cell == '.':
if alive == 3:
new[x, y, z, w] = '#'
return new
cube = defaultdict(lambda: '.')
for x, row in enumerate(startgrid):
for y, cell in enumerate(row):
cube[x, y, 0, 0] = cell
for _ in range(6):
cube = evolve4d(cube)
ans2 = sum(x == '#' for x in cube.values())
advent.print_answer(2, ans2)