advent-of-code/2017-python/solutions/day_22.py

99 lines
2.8 KiB
Python
Raw Normal View History

2021-11-01 16:40:46 +01:00
from collections import Counter
from solutions import BaseSolution
class Solution(BaseSolution):
2025-05-06 20:14:58 +02:00
input_file = "22.txt"
2021-11-01 16:40:46 +01:00
def __str__(self):
2025-05-06 20:14:58 +02:00
return "Day 22: Sporifica Virus"
2021-11-01 16:40:46 +01:00
infected = 0
def solve(self, puzzle_input, bursts=10000):
return self._calculate_infected(puzzle_input, bursts)
def solve_again(self, puzzle_input, bursts=10000000):
return self._calculate_infected(puzzle_input, bursts, evolved=True)
def _calculate_infected(self, puzzle_input, bursts, evolved=False):
dirs, amap, pos = self._setup(puzzle_input)
for _ in range(bursts):
amap, state = self._get_state(amap, pos)
dirs = self._change_dir(dirs, state)
if not evolved:
amap = self._update_state(amap, pos)
else:
amap = self._update_state_evolved(amap, pos)
pos = self._move(pos, dirs[0])
return self.infected
def _setup(self, puzzle_input):
self.infected = 0
dirs = [
(-1, 0), # up
(0, -1), # right
(1, 0), # down
(0, 1), # left
]
amap = []
pil = puzzle_input.strip().splitlines()
pos = [len(pil) // 2, len(pil[0]) // 2]
for n, line in enumerate(pil):
for nn, c in enumerate(line.strip()):
amap.append([n, nn, c])
return dirs, amap, pos
def _change_dir(self, dirs, state):
if state == ".":
dirs = dirs[1:] + [dirs[0]]
elif state == "#":
dirs = [dirs[3]] + dirs[:3]
2025-05-06 20:14:58 +02:00
elif state == "F":
2021-11-01 16:40:46 +01:00
dirs = dirs[2:] + dirs[:2]
return dirs
def _get_state(self, amap, pos):
t = lambda x: x[1][0] == pos[0] and x[1][1] == pos[1]
existing = next(filter(t, enumerate(amap)), None)
if existing:
i, p = existing
return amap, p[2]
else:
2025-05-06 20:14:58 +02:00
amap.append([pos[0], pos[1], "."])
return amap, "."
2021-11-01 16:40:46 +01:00
def _update_state(self, amap, pos):
t = lambda x: x[1][0] == pos[0] and x[1][1] == pos[1]
existing = next(filter(t, enumerate(amap)))
i, p = existing
2025-05-06 20:14:58 +02:00
if p[2] == ".":
2021-11-01 16:40:46 +01:00
self.infected += 1
2025-05-06 20:14:58 +02:00
amap[i][2] = "." if p[2] == "#" else "#"
2021-11-01 16:40:46 +01:00
return amap
def _move(self, pos, d):
return [pos[0] + d[0], pos[1] + d[1]]
def _update_state_evolved(self, amap, pos):
t = lambda x: x[1][0] == pos[0] and x[1][1] == pos[1]
existing = next(filter(t, enumerate(amap)))
i, p = existing
2025-05-06 20:14:58 +02:00
if p[2] == ".":
ns = "W"
elif p[2] == "W":
2021-11-01 16:40:46 +01:00
self.infected += 1
ns = "#"
2025-05-06 20:14:58 +02:00
elif p[2] == "#":
2021-11-01 16:40:46 +01:00
ns = "F"
else:
ns = "."
amap[i][2] = ns
return amap
2025-05-06 20:14:58 +02:00
if __name__ == "__main__":
2021-11-01 16:40:46 +01:00
solution = Solution()
solution.show_results()