From f586a35c4b24411e22a636d11426b4830500f631 Mon Sep 17 00:00:00 2001 From: derailed-dash Date: Sun, 28 Jan 2024 17:13:33 +0000 Subject: [PATCH] Doc updates --- .../Dazbo's_Advent_of_Code_2023.ipynb | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb b/src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb index ecf8a0e..c001b35 100644 --- a/src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb +++ b/src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb @@ -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", @@ -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", @@ -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", @@ -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", @@ -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", @@ -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", @@ -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",