Skip to content

Commit

Permalink
Doc updates
Browse files Browse the repository at this point in the history
  • Loading branch information
derailed-dash committed Jan 28, 2024
1 parent 6f399db commit f586a35
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -6894,8 +6894,7 @@
"locations = get_locations(d_name)\n",
"\n",
"# SETUP LOGGING\n",
"logger.setLevel(logging.DEBUG)\n",
"# td.setup_file_logging(logger, locations.output_dir)\n",
"logger.setLevel(logging.INFO)\n",
"\n",
"# Retrieve input and store in local file\n",
"try:\n",
Expand Down Expand Up @@ -6935,7 +6934,7 @@
"\n",
"The digger starts in a 1 meter cube hole in the ground and can move the specified number of metres up, down, left or right. These directions are all in the same plane (as seen from above), so we're in a 2D grid. Having followed the instructions to dig a tunnel that represents the edge of the lagoon, we then dig out the interior.\n",
"\n",
"Each trench is also listed with the color that the edge of the trench should be painted as an RGB hexadecimal color code.\n",
"Each trench is also listed with the color that the edge of the trench should be painted as an RGB hexadecimal color code. But for part 1, we don't use this information. So we only care about the first two parameters in each line.\n",
"\n",
"**If they follow their dig plan, how many cubic meters of lava could it hold?**\n",
"\n",
Expand All @@ -6949,11 +6948,11 @@
" - Whenever we reach a turn, identify the inside square that is bordered by the three squares of the turn, and flag it as an _interior candidate_. The way I identify the candidate square is to create a `2x2` square from the three squares of the turn, and then simply identify the square that is missing.\n",
" - This method returns `perimeter_path` and `interior_candidates` as a tuple.\n",
"- Next, I create `perimeter_set` from my `perimeter_path`, because this is much more efficient when checking membership. (I'll be using this later for my BFS.)\n",
"- Then I call `create_bounds()` to determine the top-left and bottom-right coordinates of all points in the perimeter.\n",
"- Then I call `create_bounds()` to determine the top-left and bottom-right coordinates of all points in the perimeter. We will use this later to form the outer bounds of our BFS.\n",
"- Now I'm ready to `flood_fill()`, to determine the interior volume of our perimeter.\n",
" - This is another [BFS flood fill](https://aoc.just2good.co.uk/python/shortest_paths).\n",
" - We create `interior` and `exterior` sets, to store points as we examine them.\n",
" - We iterating over candidate points from `interior_candidates`. If the candidate has already been placed in `interior` or `exterior`, then we can skip it.\n",
" - We iterate over candidate points from `interior_candidates`. If the candidate has already been placed in `interior` or `exterior`, then we can skip it.\n",
" - Otherwise, we set up a BFS to expand from this particular candidate. \n",
" - The BFS expands in each direction, until it reaches a perimeter point, or the boundary of the grid.\n",
" - With each point we find, we add it to a set called `region`.\n",
Expand Down Expand Up @@ -7013,7 +7012,8 @@
" \n",
" return plan\n",
"\n",
"def process_plan(plan) -> tuple[list, set]:\n",
"def process_plan(plan: list) -> tuple[list, set]:\n",
" \"\"\" Determine perimeter path and interior candidates. \"\"\"\n",
" perimeter_path = []\n",
" current = (0,0)\n",
" perimeter_path.append(current)\n",
Expand Down Expand Up @@ -7041,6 +7041,7 @@
" return perimeter_path, interior_candidates\n",
"\n",
"def get_bounds(perimeter_path: list[tuple[int,int]]) -> tuple[tuple, tuple]:\n",
" \"\"\" Given a path of points, determine the top left and bottom right coordinates. \"\"\"\n",
" min_x = min(perimeter_path, key=lambda p: p[0])[0]\n",
" max_x = max(perimeter_path, key=lambda p: p[0])[0]\n",
" min_y = min(perimeter_path, key=lambda p: p[1])[1]\n",
Expand All @@ -7049,13 +7050,23 @@
" return ((min_x, min_y), (max_x, max_y)) # tl, br\n",
"\n",
"def flood_fill(perimeter_set, interior_candidates: set[tuple], bounds: tuple[tuple, tuple]) -> set[tuple]:\n",
" \"\"\" Perform a BFS flood fill, to determine the interior volume of our perimeter.\n",
"\n",
" Args:\n",
" perimeter_set (_type_): all coordinates that make up the perimeter\n",
" interior_candidates (set[tuple]): interior candidates, that are the inside of a turn.\n",
" bounds (tuple[tuple, tuple]): top left, bottom right. Used to form the bounds of our BFS.\n",
"\n",
" Returns:\n",
" set[tuple]: _description_\n",
" \"\"\"\n",
" min_x, min_y = bounds[0]\n",
" max_x, max_y = bounds[1]\n",
" exterior = set()\n",
" interior = set()\n",
"\n",
" logger.debug(f\"Processing {len(interior_candidates)} interior candidates.\") \n",
" for point in interior_candidates:\n",
" for point in interior_candidates: # try a BFS from each interior point\n",
" if point in interior or point in exterior:\n",
" continue # this point is in a region we've done already\n",
" \n",
Expand All @@ -7069,10 +7080,10 @@
" while queue and is_interior:\n",
" current = queue.popleft()\n",
" \n",
" if current in interior:\n",
" if current in interior: # we've seen this interior point before\n",
" break\n",
" \n",
" if current not in perimeter_set:\n",
" if current not in perimeter_set: # we need to ignore points in the perimeter\n",
" region.add(current)\n",
" \n",
" neighbours = [(current[0]+dx, current[1]+dy) for dx,dy in (VectorDicts.DIRS.values())]\n",
Expand Down

0 comments on commit f586a35

Please sign in to comment.