Skip to content

Commit

Permalink
Making d23 BFS recursive
Browse files Browse the repository at this point in the history
  • Loading branch information
derailed-dash committed Dec 27, 2023
1 parent 4eacb2a commit bc9ece9
Showing 1 changed file with 40 additions and 7 deletions.
47 changes: 40 additions & 7 deletions src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -8918,7 +8918,8 @@
" return vertices\n",
" \n",
"def build_edges(grid, vertices: set[tuple[int,int]], part) -> dict[tuple, set]:\n",
" \"\"\" BFS from each vertex to find all connected vertices \"\"\"\n",
" \"\"\" BFS from each vertex to find all connected vertices. It returns an adjacency list \n",
" mapping each vertex to all adjacent vertices, along with distance. \"\"\"\n",
" edges: dict[tuple, set] = defaultdict(set) # { { edge_1: { (edge_2, distance), (edge_3, distance), ... }, ... }\n",
" \n",
" for vertex in vertices:\n",
Expand All @@ -8933,7 +8934,7 @@
" \n",
" explored.add((x, y))\n",
" \n",
" # for each direction arrow...\n",
" # for each direction arrow, return the zip, e.g. (`<`, (-1, 0))\n",
" for arrow, (dx, dy) in zip(VectorDicts.ARROWS, VectorDicts.ARROWS.values()):\n",
" next_x, next_y = x+dx, y+dy\n",
" if (0 <= next_x < len(grid[0]) and 0 <= next_y < len(grid)\n",
Expand All @@ -8955,7 +8956,8 @@
"\n",
"def find_paths_dfs(grid, start: tuple, end: tuple, edges: dict[tuple, set]) -> list[int]:\n",
" \"\"\" Find all valid paths by DFS, between start and end, \n",
" using a supplied dict of vertices mapped to edges and respective distances. \"\"\"\n",
" using a supplied dict of vertices mapped to edges and respective distances. \n",
" This is slower than doing the DFS recursively, so I'm not using this function anymore. \"\"\"\n",
" assert start in edges, \"Start must be our first edge\"\n",
"\n",
" stack = deque() # vertices to visit\n",
Expand All @@ -8977,6 +8979,36 @@
" \n",
" return valid_paths_lengths \n",
"\n",
"def dfs(grid, edges: dict[tuple, set], from_vertex: tuple, goal: tuple, seen: set=set()) -> list:\n",
" \"\"\" Recursive DFS to find all path lengths from from_vertex to goal. \n",
"\n",
" Args:\n",
" grid (_type_): _description_\n",
" edges (dict[tuple, set]): Adjacency dictionary mapping vertex to a set of (vertex, distance)\n",
" from_vertex (tuple): The current vertex\n",
" goal (tuple): The final vertex we want to reach\n",
" seen (set, optional): To track visisted vertices. First call will set it to empty.\n",
"\n",
" Returns:\n",
" list: lengths of all valid paths\n",
" \"\"\"\n",
" if from_vertex == goal:\n",
" return [0] # Found a path, return a list with length 0 (since no more distance is needed)\n",
" \n",
" seen.add(from_vertex) # tp prevent backtracking in THIS path\n",
" path_lengths = []\n",
" \n",
" # explore each connected vertex\n",
" for next_vertex, distance in edges[from_vertex]:\n",
" if next_vertex not in seen: # prevent backtracking for this path\n",
" # recursively call from the next vertex onwards\n",
" for path_len in dfs(grid, edges, next_vertex, goal, seen):\n",
" path_lengths.append(path_len + distance) # adjust each length by adding the current dist\n",
" \n",
" seen.remove(from_vertex) # to allow other paths to visit this vertex\n",
" \n",
" return path_lengths\n",
"\n",
"def draw_graph(graph, start, end):\n",
" # Create a list of colors, one for each node\n",
" node_colors = ['blue' if node not in [start, end] else 'red' for node in graph.nodes()]\n",
Expand Down Expand Up @@ -9020,7 +9052,8 @@
" \n",
" draw_graph(graph, start, end) # let's have a look at it\n",
" \n",
" valid_path_lengths = find_paths_dfs(grid, start, end, edges)\n",
" # valid_path_lengths = find_paths_dfs(grid, start, end, edges)\n",
" valid_path_lengths = dfs(grid, edges, start, end)\n",
" \n",
" return max(valid_path_lengths)"
]
Expand Down Expand Up @@ -9074,13 +9107,13 @@
"source": [
"### Day 23 Part 2\n",
"\n",
"Now we can ignore the arrows. They just behave like normal path `.`.\n",
"Now we can ignore the arrows. They just behave like normal path `.` locations.\n",
"\n",
"**Find the longest hike you can take through the surprisingly dry hiking trails listed on your map. How many steps long is the longest hike?**\n",
"\n",
"Here, all we need to do is removed the check for the direction arrow. It does make the resulting graph significantly more complicated, and makes the number of valid paths huge.\n",
"Here, all we need to do is remove the check for the direction arrow. It does make the resulting graph significantly more complicated, and makes the number of valid paths huge.\n",
"\n",
"But the solution still runs in a reasonable amount of time."
"But the solution still runs in a reasonable amount of time. This is because we've already applied the edge contraction, so the number of paths we have to test is significantly smaller than it would have been."
]
},
{
Expand Down

0 comments on commit bc9ece9

Please sign in to comment.