Day 16: The Floor Will Be Lava
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
Python
Also on Github
53.059 line-seconds (ranks third hardest after days 8 and 12 so far).
from .solver import Solver def _trace_beam(data, initial_beam_head): wx = len(data[0]) wy = len(data) beam_heads = [initial_beam_head] seen_beam_heads = set() while beam_heads: next_beam_heads = [] for x, y, dx, dy in beam_heads: seen_beam_heads.add((x, y, dx, dy)) nx, ny = (x + dx), (y + dy) if nx < 0 or nx >= wx or ny < 0 or ny >= wy: continue obj = data[ny][nx] if obj == '|' and dx != 0: next_beam_heads.append((nx, ny, 0, 1)) next_beam_heads.append((nx, ny, 0, -1)) elif obj == '-' and dy != 0: next_beam_heads.append((nx, ny, 1, 0)) next_beam_heads.append((nx, ny, -1, 0)) elif obj == '/': next_beam_heads.append((nx, ny, -dy, -dx)) elif obj == '\\': next_beam_heads.append((nx, ny, dy, dx)) else: next_beam_heads.append((nx, ny, dx, dy)) beam_heads = [x for x in next_beam_heads if x not in seen_beam_heads] energized = {(x, y) for x, y, _, _ in seen_beam_heads} return len(energized) - 1 class Day16(Solver): def __init__(self): super().__init__(16) def presolve(self, input: str): data = input.splitlines() self.possible_energized_cells = ( [_trace_beam(data, (-1, y, 1, 0)) for y in range(len(data))] + [_trace_beam(data, (x, -1, 0, 1)) for x in range(len(data[0]))] + [_trace_beam(data, (len(data[0]), y, -1, 0)) for y in range(len(data))] + [_trace_beam(data, (x, len(data), 0, -1)) for x in range(len(data[0]))]) def solve_first_star(self) -> int: return self.possible_energized_cells[0] def solve_second_star(self) -> int: return max(self.possible_energized_cells)