Skip to content

Commit

Permalink
[2024/6] p2 solved (slow - takes 5m30s)
Browse files Browse the repository at this point in the history
  • Loading branch information
StarlitGhost committed Dec 6, 2024
1 parent 84ffacf commit 7c4dbe4
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 10 deletions.
Binary file modified .aoc_tiles/tiles/2024/06.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 73 additions & 8 deletions 2024/6/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,93 @@ def move(pos: tuple, dir_: Dir, grid: Grid) -> tuple[tuple, Dir]:
next_pos = pos + Vec2(dir_)

# out of bounds or open, return next position
if not grid.in_bounds(next_pos) or not grid[next_pos] == '#':
if not grid.in_bounds(next_pos) or not grid[next_pos] in '#O':
return next_pos.as_tuple(), dir_

# obstacle, rotate right 90 degrees
else:
return pos, dir_.turn_right()


def main():
grid = Grid(aoc.read_lines())

pos = grid.find('^')
dir_ = Dir.UP

def simulate(pos: tuple, dir_: Dir, grid: Grid) -> tuple[set, list, bool]:
visited = set()
visited.add(pos)
path = []
path.append((pos, dir_))
loops = False

while grid.in_bounds(pos):
pos, dir_ = move(pos, dir_, grid)
visited.add(pos)
if path[-1][0] == pos:
path.append((pos, dir_))
path.append((pos, None))
elif (pos, dir_) in path:
loops = True
break
else:
path.append((pos, dir_))

return visited, path, loops


def print_path(grid: Grid, path: list, start_pos: tuple):
dir_chars = {
Dir.UP: '|',
Dir.DOWN: '|',
Dir.LEFT: '-',
Dir.RIGHT: '-',
None: '+',
}
print(grid.render_with_overlays([{pos: dir_chars[dir_] for pos, dir_ in path},
{start_pos: '^'}]))


def main():
grid = Grid(aoc.read_lines())

start_pos = grid.find('^')
dir_ = Dir.UP

visited, path, _ = simulate(start_pos, dir_, grid)

# print(grid.render_with_overlays([{pos: 'X' for pos in visited}]))
# print("p1:", len(visited) - 1)

# print_path(grid, path, start_pos)

loop_obstacles = set()
tried_obstacles = set()
path = [p for p in path if p[1] is not None]

# try placing an obstacle at every position along our initial path
for i, pair in enumerate(path):
pos = pair[0]

# skip the start position, out-of-bounds, and previously tried obstacles
if pos == start_pos or not grid.in_bounds(pos) or pos in tried_obstacles:
continue

# place the obstacle
grid[pos] = 'O'
tried_obstacles.add(pos)

# start pathing from just before the newly placed obstacle
new_start_pos, new_dir = path[i-1] if path[i-1][0] != pos else path[i-2]

new_visited, new_path, loops = simulate(new_start_pos, new_dir, grid)

# track obstacles that cause loops
if loops:
loop_obstacles.add(pos)
# print_path(grid, new_path, new_start_pos)
print(f"{i}/{len(path)} {len(loop_obstacles)}")

# remove the current obstacle so we can try the next one
grid[pos] = '.'

print(grid.render_with_overlays([{pos: 'X' for pos in visited}]))
print("p1:", len(visited) - 1)
print("p2:", len(loop_obstacles))


if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ My solutions to the yearly Advents of Code

<!-- AOC TILES BEGIN -->
<h1 align="center">
Advent of Code - 172/462 ⭐
Advent of Code - 173/462 ⭐
</h1>
<h1 align="center">
2024 - 11 ⭐ - Python
2024 - 12 ⭐ - Python
</h1>
<a href="2024/1/script.py">
<img src=".aoc_tiles/tiles/2024/01.png" width="161px">
Expand Down

0 comments on commit 7c4dbe4

Please sign in to comment.