2021-11-01 16:40:46 +01:00
|
|
|
import itertools
|
|
|
|
|
|
|
|
|
|
from solutions import BaseSolution
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Solution(BaseSolution):
|
2025-05-06 20:14:58 +02:00
|
|
|
input_file = "13.txt"
|
2021-11-01 16:40:46 +01:00
|
|
|
layers = []
|
|
|
|
|
scanners = []
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
2025-05-06 20:14:58 +02:00
|
|
|
return "Day 13: Packet Scanners"
|
2021-11-01 16:40:46 +01:00
|
|
|
|
|
|
|
|
def _move_scanners(self):
|
|
|
|
|
for p, l in enumerate(self.layers):
|
|
|
|
|
if l != 0:
|
|
|
|
|
self.scanners[p][0] += self.scanners[p][1]
|
|
|
|
|
if self.scanners[p][0] == l - 1 or self.scanners[p][0] == 0:
|
|
|
|
|
self.scanners[p][1] = -self.scanners[p][1]
|
|
|
|
|
|
|
|
|
|
def _init_scanners(self):
|
|
|
|
|
self.scanners = [[0, 1] for l in self.layers]
|
|
|
|
|
|
|
|
|
|
def _setup(self, puzzle_input):
|
2025-05-06 20:14:58 +02:00
|
|
|
pi = [
|
|
|
|
|
tuple(map(int, line.strip().split(": ")))
|
|
|
|
|
for line in puzzle_input.splitlines()
|
|
|
|
|
]
|
2021-11-01 16:40:46 +01:00
|
|
|
self.layers = [0 for _ in range(pi[-1][0] + 1)]
|
|
|
|
|
self._init_scanners()
|
|
|
|
|
for k, v in pi:
|
|
|
|
|
self.layers[k] = v
|
|
|
|
|
|
|
|
|
|
def _get_severity(self):
|
|
|
|
|
severity = 0
|
|
|
|
|
for pos in range(len(self.layers)):
|
|
|
|
|
if self.scanners[pos][0] == 0 and self.layers[pos] > 0:
|
|
|
|
|
severity += self.layers[pos] * pos
|
|
|
|
|
self._move_scanners()
|
|
|
|
|
return severity
|
|
|
|
|
|
|
|
|
|
def _will_be_caught(self):
|
|
|
|
|
caught = False
|
|
|
|
|
for pos, l in enumerate(self.layers):
|
|
|
|
|
if l > 0 and self.scanners[pos][0] == 0:
|
|
|
|
|
caught = True
|
|
|
|
|
self._move_scanners()
|
|
|
|
|
return caught
|
|
|
|
|
|
|
|
|
|
def solve(self, puzzle_input):
|
|
|
|
|
self._setup(puzzle_input)
|
|
|
|
|
severity = self._get_severity()
|
|
|
|
|
return severity
|
|
|
|
|
|
|
|
|
|
def _scan(self, height, time):
|
|
|
|
|
offset = time % ((height - 1) * 2)
|
|
|
|
|
return 2 * (height - 1) - offset if offset > height - 1 else offset
|
|
|
|
|
|
|
|
|
|
def solve_again(self, puzzle_input):
|
|
|
|
|
# todo: rewrite!
|
2025-05-06 20:14:58 +02:00
|
|
|
lines = [line.split(": ") for line in puzzle_input.splitlines()]
|
2021-11-01 16:40:46 +01:00
|
|
|
heights = {int(pos): int(height) for pos, height in lines}
|
|
|
|
|
wait = next(
|
2025-05-06 20:14:58 +02:00
|
|
|
wait
|
|
|
|
|
for wait in itertools.count()
|
|
|
|
|
if not any(self._scan(heights[pos], wait + pos) == 0 for pos in heights)
|
|
|
|
|
)
|
2021-11-01 16:40:46 +01:00
|
|
|
return wait
|
|
|
|
|
|
|
|
|
|
|
2025-05-06 20:14:58 +02:00
|
|
|
if __name__ == "__main__":
|
2021-11-01 16:40:46 +01:00
|
|
|
solution = Solution()
|
|
|
|
|
solution.show_results()
|