Skip to content

Commit 749b8e5

Browse files
committed
Improved performance for 2020-11 and 2020-17
1 parent d83174e commit 749b8e5

File tree

5 files changed

+731
-139
lines changed

5 files changed

+731
-139
lines changed

2020/11-Seating System.py

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -138,67 +138,52 @@ def words(s: str):
138138

139139
else:
140140

141-
def get_neighbors_map(dot):
141+
def get_neighbors_map(grid, dot):
142142
neighbors = []
143-
if dot.grid.width is None:
144-
dot.grid.get_size()
145-
for direction in dot.allowed_directions:
143+
for direction in directions_diagonals:
146144
neighbor = dot + direction
147-
while neighbor is not None:
148-
if neighbor.terrain in ("L", "#"):
149-
neighbors.append(neighbor.position)
145+
while neighbor in grid.dots:
146+
if grid.dots[neighbor] in ("L", "#"):
147+
neighbors.append(neighbor)
150148
break
151149
else:
152150
neighbor += direction
153151
return neighbors
154152

155153
seats = grid.Grid()
156-
seats.all_directions = directions_diagonals
157154
seats.text_to_dots(puzzle_input)
158-
seats.neighbors_map = {
159-
dot: get_neighbors_map(seats.dots[dot]) for dot in seats.dots
160-
}
161-
162-
new_seats = copy.deepcopy(seats)
155+
seats.width = len(puzzle_input.split("\n")[0])
156+
seats.height = len(puzzle_input.split("\n"))
163157

164-
def get_neighbors(self):
165-
return {
166-
self.grid.dots[neighbor]: 1
167-
for neighbor in self.grid.neighbors_map[self.position]
168-
}
158+
seats.dots = {dot: seats.dots[dot].terrain for dot in seats.dots}
159+
seats.neighbors_map = {dot: get_neighbors_map(seats, dot) for dot in seats.dots}
169160

170-
dot.Dot.get_neighbors = get_neighbors
161+
new_seats = grid.Grid()
162+
new_seats.dots = seats.dots.copy()
171163

172-
i = 0
164+
# #copy.deepcopy(seats)
173165

174166
while True:
175-
i += 1
176-
watch = [2]
177-
for dot in seats.dots:
178-
if seats.dots[dot].terrain == "L" and all(
179-
[d.terrain in ("L", ".") for d in seats.dots[dot].get_neighbors()]
167+
for dot, terrain in seats.dots.items():
168+
if terrain == "L" and all(
169+
[seats.dots[d] in ("L", ".") for d in seats.neighbors_map[dot]]
180170
):
181-
new_seats.dots[dot].terrain = "#"
171+
new_seats.dots[dot] = "#"
182172
elif (
183-
seats.dots[dot].terrain == "#"
184-
and sum(
185-
[1 for d in seats.dots[dot].get_neighbors() if d.terrain == "#"]
186-
)
173+
terrain == "#"
174+
and sum([1 for d in seats.neighbors_map[dot] if seats.dots[d] == "#"])
187175
>= 5
188176
):
189-
new_seats.dots[dot].terrain = "L"
177+
new_seats.dots[dot] = "L"
190178
else:
191-
new_seats.dots[dot].terrain = seats.dots[dot].terrain
179+
new_seats.dots[dot] = terrain
192180

193-
if all(
194-
[seats.dots[d].terrain == new_seats.dots[d].terrain for d in seats.dots]
195-
):
181+
if all([seats.dots[d] == new_seats.dots[d] for d in seats.dots]):
196182
break
197183

198-
seats = copy.deepcopy(new_seats)
199-
# #print(i)
184+
seats.dots = new_seats.dots.copy()
200185

201-
puzzle_actual_result = sum([1 for d in seats.dots if seats.dots[d].terrain == "#"])
186+
puzzle_actual_result = sum([1 for d in seats.dots if seats.dots[d] == "#"])
202187

203188

204189
# -------------------------------- Outputs / results --------------------------------- #

2020/11-Seating System.v1.py

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, grid, graph, dot, assembly, re, itertools
3+
from collections import Counter, deque, defaultdict
4+
import copy
5+
from compass import *
6+
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": """L.LL.LL.LL
38+
LLLLLLL.LL
39+
L.L.L..L..
40+
LLLL.LL.LL
41+
L.LL.LL.LL
42+
L.LLLLL.LL
43+
..L.L.....
44+
LLLLLLLLLL
45+
L.LLLLLL.L
46+
L.LLLLL.LL""",
47+
"expected": ["37", "26"],
48+
}
49+
50+
test = "real"
51+
input_file = os.path.join(
52+
os.path.dirname(__file__),
53+
"Inputs",
54+
os.path.basename(__file__).replace(".py", ".txt"),
55+
)
56+
test_data[test] = {
57+
"input": open(input_file, "r+").read(),
58+
"expected": ["2324", "2068"],
59+
}
60+
61+
62+
# -------------------------------- Control program execution ------------------------- #
63+
64+
case_to_test = "real"
65+
part_to_test = 2
66+
67+
# -------------------------------- Initialize some variables ------------------------- #
68+
69+
puzzle_input = test_data[case_to_test]["input"]
70+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
71+
puzzle_actual_result = "Unknown"
72+
73+
74+
# -------------------------------- Actual code execution ----------------------------- #
75+
76+
77+
dot.all_directions = directions_diagonals
78+
all_directions = directions_diagonals
79+
dot.Dot.allowed_direction_map = {
80+
".": {dir: all_directions for dir in all_directions},
81+
"#": {},
82+
" ": {},
83+
"+": {dir: all_directions for dir in all_directions},
84+
"|": {north: [north, south], south: [north, south]},
85+
"^": {north: [north, south], south: [north, south]},
86+
"v": {north: [north, south], south: [north, south]},
87+
"-": {east: [east, west], west: [east, west]},
88+
">": {east: [east, west], west: [east, west]},
89+
"<": {east: [east, west], west: [east, west]},
90+
"\\": {north: [east], east: [north], south: [west], west: [south]},
91+
"/": {north: [west], east: [south], south: [east], west: [north]},
92+
"X": {dir: all_directions for dir in all_directions},
93+
}
94+
95+
96+
grid.Grid.all_directions = directions_diagonals
97+
98+
if part_to_test == 1:
99+
seats = grid.Grid()
100+
seats.all_directions = directions_diagonals
101+
seats.text_to_dots(puzzle_input)
102+
103+
new_seats = grid.Grid()
104+
new_seats.all_directions = directions_diagonals
105+
new_seats.text_to_dots(puzzle_input)
106+
107+
i = 0
108+
while True:
109+
i += 1
110+
watch = [1 - 1j]
111+
for dot in seats.dots:
112+
if seats.dots[dot].terrain == "L" and all(
113+
[d.terrain in ("L", ".") for d in seats.dots[dot].get_neighbors()]
114+
):
115+
new_seats.dots[dot].terrain = "#"
116+
elif (
117+
seats.dots[dot].terrain == "#"
118+
and sum(
119+
[1 for d in seats.dots[dot].get_neighbors() if d.terrain == "#"]
120+
)
121+
>= 4
122+
):
123+
new_seats.dots[dot].terrain = "L"
124+
else:
125+
new_seats.dots[dot].terrain = seats.dots[dot].terrain
126+
127+
if all(
128+
[seats.dots[d].terrain == new_seats.dots[d].terrain for d in seats.dots]
129+
):
130+
break
131+
132+
seats = copy.deepcopy(new_seats)
133+
new_seats.text_to_dots(puzzle_input)
134+
# #print(i)
135+
136+
puzzle_actual_result = sum([1 for d in seats.dots if seats.dots[d].terrain == "#"])
137+
138+
139+
else:
140+
141+
def get_neighbors_map(dot):
142+
neighbors = []
143+
if dot.grid.width is None:
144+
dot.grid.get_size()
145+
for direction in dot.allowed_directions:
146+
neighbor = dot + direction
147+
while neighbor is not None:
148+
if neighbor.terrain in ("L", "#"):
149+
neighbors.append(neighbor.position)
150+
break
151+
else:
152+
neighbor += direction
153+
return neighbors
154+
155+
seats = grid.Grid()
156+
seats.all_directions = directions_diagonals
157+
seats.text_to_dots(puzzle_input)
158+
seats.neighbors_map = {
159+
dot: get_neighbors_map(seats.dots[dot]) for dot in seats.dots
160+
}
161+
162+
new_seats = copy.deepcopy(seats)
163+
164+
def get_neighbors(self):
165+
return {
166+
self.grid.dots[neighbor]: 1
167+
for neighbor in self.grid.neighbors_map[self.position]
168+
}
169+
170+
dot.Dot.get_neighbors = get_neighbors
171+
172+
i = 0
173+
174+
while True:
175+
i += 1
176+
watch = [2]
177+
for dot in seats.dots:
178+
if seats.dots[dot].terrain == "L" and all(
179+
[d.terrain in ("L", ".") for d in seats.dots[dot].get_neighbors()]
180+
):
181+
new_seats.dots[dot].terrain = "#"
182+
elif (
183+
seats.dots[dot].terrain == "#"
184+
and sum(
185+
[1 for d in seats.dots[dot].get_neighbors() if d.terrain == "#"]
186+
)
187+
>= 5
188+
):
189+
new_seats.dots[dot].terrain = "L"
190+
else:
191+
new_seats.dots[dot].terrain = seats.dots[dot].terrain
192+
193+
if all(
194+
[seats.dots[d].terrain == new_seats.dots[d].terrain for d in seats.dots]
195+
):
196+
break
197+
198+
seats = copy.deepcopy(new_seats)
199+
# #print(i)
200+
201+
puzzle_actual_result = sum([1 for d in seats.dots if seats.dots[d].terrain == "#"])
202+
203+
204+
# -------------------------------- Outputs / results --------------------------------- #
205+
206+
print("Case :", case_to_test, "- Part", part_to_test)
207+
print("Expected result : " + str(puzzle_expected_result))
208+
print("Actual result : " + str(puzzle_actual_result))
209+
# Date created: 2020-12-11 06:00:07.140562
210+
# Part 1: 2020-12-11 06:22:46
211+
# Part 2: 2020-12-11 06:37:29

0 commit comments

Comments
 (0)