Skip to content

Commit 0f388d1

Browse files
committed
Added day 2020-17
1 parent 7b03bf8 commit 0f388d1

File tree

1 file changed

+248
-0
lines changed

1 file changed

+248
-0
lines changed

2020/17-Conway Cubes.py

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, grid, graph, dot, assembly, re, itertools
3+
from collections import Counter, deque, defaultdict
4+
5+
from compass import *
6+
from copy import deepcopy
7+
8+
# This functions come from https://github.com/mcpower/adventofcode - Thanks!
9+
def lmap(func, *iterables):
10+
return list(map(func, *iterables))
11+
12+
13+
def ints(s: str):
14+
return lmap(int, re.findall(r"-?\d+", s)) # thanks mserrano!
15+
16+
17+
def positive_ints(s: str):
18+
return lmap(int, re.findall(r"\d+", s)) # thanks mserrano!
19+
20+
21+
def floats(s: str):
22+
return lmap(float, re.findall(r"-?\d+(?:\.\d+)?", s))
23+
24+
25+
def positive_floats(s: str):
26+
return lmap(float, re.findall(r"\d+(?:\.\d+)?", s))
27+
28+
29+
def words(s: str):
30+
return re.findall(r"[a-zA-Z]+", s)
31+
32+
33+
test_data = {}
34+
35+
test = 1
36+
test_data[test] = {
37+
"input": """.#.
38+
..#
39+
###""",
40+
"expected": ["112", "848"],
41+
}
42+
43+
test = "real"
44+
input_file = os.path.join(
45+
os.path.dirname(__file__),
46+
"Inputs",
47+
os.path.basename(__file__).replace(".py", ".txt"),
48+
)
49+
test_data[test] = {
50+
"input": open(input_file, "r+").read(),
51+
"expected": ["348", "2236"],
52+
}
53+
54+
55+
# -------------------------------- Control program execution ------------------------- #
56+
57+
case_to_test = "real"
58+
part_to_test = 2
59+
60+
# -------------------------------- Initialize some variables ------------------------- #
61+
62+
puzzle_input = test_data[case_to_test]["input"]
63+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
64+
puzzle_actual_result = "Unknown"
65+
66+
67+
# -------------------------------- Actual code execution ----------------------------- #
68+
69+
70+
class Grid_3D:
71+
def __init__(self, dots={}):
72+
self.dots = dots
73+
74+
75+
class Dot_3D:
76+
def __init__(self, grid, x, y, z, state):
77+
self.grid = grid
78+
self.x = x
79+
self.y = y
80+
self.z = z
81+
self.state = state
82+
83+
def neighbors(self):
84+
return [
85+
self.grid.dots[(self.x + a, self.y + b, self.z + c)]
86+
for a in range(-1, 2)
87+
for b in range(-1, 2)
88+
for c in range(-1, 2)
89+
if (a, b, c) != (0, 0, 0)
90+
and (self.x + a, self.y + b, self.z + c) in self.grid.dots
91+
]
92+
93+
def active_neighbors(self):
94+
return sum([1 for neighbor in self.neighbors() if neighbor.state == "#"])
95+
96+
97+
class Grid_4D:
98+
def __init__(self, dots={}):
99+
self.dots = dots
100+
101+
102+
class Dot_4D:
103+
def __init__(self, grid, x, y, z, w, state):
104+
self.grid = grid
105+
self.x = x
106+
self.y = y
107+
self.z = z
108+
self.w = w
109+
self.state = state
110+
111+
def neighbors(self):
112+
return [
113+
self.grid.dots[(self.x + a, self.y + b, self.z + c, self.w + d)]
114+
for a in range(-1, 2)
115+
for b in range(-1, 2)
116+
for c in range(-1, 2)
117+
for d in range(-1, 2)
118+
if (a, b, c, d) != (0, 0, 0, 0)
119+
and (self.x + a, self.y + b, self.z + c, self.w + d) in self.grid.dots
120+
]
121+
122+
def active_neighbors(self):
123+
return sum([1 for neighbor in self.neighbors() if neighbor.state == "#"])
124+
125+
126+
if part_to_test == 1:
127+
margin = 7
128+
grid = Grid_3D()
129+
size = len(puzzle_input.split("\n"))
130+
for x in range(-margin, size + margin):
131+
for y in range(-margin, size + margin):
132+
for z in range(-margin, size + margin):
133+
grid.dots[(x, y, z)] = Dot_3D(grid, x, y, z, ".")
134+
135+
for y, line in enumerate(puzzle_input.split("\n")):
136+
for x, cell in enumerate(line):
137+
grid.dots[(x, y, 0)] = Dot_3D(grid, x, y, 0, cell)
138+
139+
for cycle in range(6):
140+
print("Cycle = ", cycle + 1)
141+
# #print ('Before')
142+
143+
# #for z in range (-margin, size+margin):
144+
# #print ('\nz=' + str(z) + '\n')
145+
# #for y in range (-margin, size+margin):
146+
# #for x in range (-margin, size+margin):
147+
# #print (grid.dots[(x, y, z)].state, end='')
148+
# #print ('')
149+
150+
new_grid = deepcopy(grid)
151+
# #print ([neighbor.state + '@' + str(neighbor.x) + ',' + str(neighbor.y) + ',' + str(neighbor.z) for neighbor in new_grid.dots[(0,0,0)].neighbors()])
152+
153+
for dot in grid.dots:
154+
if grid.dots[dot].state == "#" and grid.dots[dot].active_neighbors() in (
155+
2,
156+
3,
157+
):
158+
new_grid.dots[dot].state = "#"
159+
elif grid.dots[dot].state == "#":
160+
new_grid.dots[dot].state = "."
161+
elif grid.dots[dot].state == "." and grid.dots[dot].active_neighbors() == 3:
162+
new_grid.dots[dot].state = "#"
163+
164+
# #print ('After')
165+
# #for z in range (-margin, size+margin):
166+
# #print ('\nz=' + str(z) + '\n')
167+
# #for y in range (-margin, size+margin):
168+
# #for x in range (-margin, size+margin):
169+
# #print (new_grid.dots[(x, y, z)].state, end='')
170+
# #print ('')
171+
172+
grid = deepcopy(new_grid)
173+
174+
puzzle_actual_result = sum([1 for dot in grid.dots if grid.dots[dot].state == "#"])
175+
176+
177+
else:
178+
margin = 7
179+
grid = Grid_4D()
180+
size = len(puzzle_input.split("\n"))
181+
for x in range(-margin, size + margin):
182+
for y in range(-margin, size + margin):
183+
for z in range(-margin, size + margin):
184+
for w in range(-margin, size + margin):
185+
grid.dots[(x, y, z, w)] = Dot_4D(grid, x, y, z, w, ".")
186+
187+
for y, line in enumerate(puzzle_input.split("\n")):
188+
for x, cell in enumerate(line):
189+
grid.dots[(x, y, 0, 0)] = Dot_4D(grid, x, y, 0, 0, cell)
190+
191+
for cycle in range(6):
192+
# #print ('Cycle = ', cycle+1)
193+
# #print ('Before')
194+
195+
# #for w in range (-margin, size+margin):
196+
# #print ('\n w=' + str(w))
197+
# #for z in range (-margin, size+margin):
198+
# #print ('\nz=' + str(z))
199+
# #level = ''
200+
# #for y in range (-margin, size+margin):
201+
# #for x in range (-margin, size+margin):
202+
# #level += grid.dots[(x, y, z, w)].state
203+
# #level += '\n'
204+
# #if '#' in level:
205+
# #print (level)
206+
207+
new_grid = deepcopy(grid)
208+
watchdot = (1, 0, 0, 0)
209+
# #print (watchdot, grid.dots[watchdot].state, grid.dots[watchdot].active_neighbors())
210+
# #print ([neighbor.state + '@' + str(neighbor.x) + ',' + str(neighbor.y) + ',' + str(neighbor.z) + ',' + str(neighbor.w) for neighbor in grid.dots[(1,0,0,0)].neighbors()])
211+
# #print (grid.dots[(1,0,0,0)].active_neighbors())
212+
213+
for dot in grid.dots:
214+
if grid.dots[dot].state == "#" and grid.dots[dot].active_neighbors() in (
215+
2,
216+
3,
217+
):
218+
new_grid.dots[dot].state = "#"
219+
elif grid.dots[dot].state == "#":
220+
new_grid.dots[dot].state = "."
221+
elif grid.dots[dot].state == "." and grid.dots[dot].active_neighbors() == 3:
222+
new_grid.dots[dot].state = "#"
223+
224+
# #print (watchdot, new_grid.dots[watchdot].state, new_grid.dots[watchdot].active_neighbors())
225+
226+
# #print ('After')
227+
# #for w in range (-margin, size+margin):
228+
# #print ('\nw=' + str(w) + '\n')
229+
# #for z in range (-margin, size+margin):
230+
# #print ('\nz=' + str(z) + '\n')
231+
# #for y in range (-margin, size+margin):
232+
# #for x in range (-margin, size+margin):
233+
# #print (new_grid.dots[(x, y, z, w)].state, end='')
234+
# #print ('')
235+
236+
grid = deepcopy(new_grid)
237+
238+
puzzle_actual_result = sum([1 for dot in grid.dots if grid.dots[dot].state == "#"])
239+
240+
241+
# -------------------------------- Outputs / results --------------------------------- #
242+
243+
print("Case :", case_to_test, "- Part", part_to_test)
244+
print("Expected result : " + str(puzzle_expected_result))
245+
print("Actual result : " + str(puzzle_actual_result))
246+
# Date created: 2020-12-17 06:00:01.401422
247+
# Part 1: 2020-12-17 06:28:49
248+
# Part 2: 2020-12-17 06:50:40

0 commit comments

Comments
 (0)