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 c85f57f..caf987b 100644 --- a/src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb +++ b/src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb @@ -4032,7 +4032,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Final Remarks and Useful Resources\n", + "### Altternative Solutions and Useful Resources\n", "\n", "There are a few other ways to solve this problem. \n", "\n", @@ -4048,6 +4048,29 @@ "- For simplicity, we could have easily replaced all non-loop pipe components with `.`. (Since we already know which points make up the loop itself.)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def shoelace_area(polygon: list[Point]) -> int:\n", + " \"\"\" Use Shoelace formula to determine total area of a polygon:\n", + " A = 1/2 sum(x * (y+1 - y-1)) \"\"\"\n", + " total = 0\n", + " for i, (point) in enumerate(polygon):\n", + " next_index = (i+1) % len(polygon)\n", + " prev_index = i-1\n", + " total += point.x*(polygon[next_index].y - polygon[prev_index].y)\n", + " \n", + " return abs(total) // 2\n", + "\n", + "def interior_points(area: int, boundary_points: int):\n", + " \"\"\" Use Pick's Theorem to determine total number of internal integer points, \n", + " given a polygon area and number of boundary points. \"\"\"\n", + " return area - (boundary_points // 2) + 1 " + ] + }, { "cell_type": "code", "execution_count": null, @@ -4056,10 +4079,15 @@ "source": [ "def d10_with_shoelace_and_picks(grid: PipeGrid, furthest: Point, came_from: dict[Point, tuple]):\n", " \"\"\" Determine number of tiles (which can be empty or non-loop pipe components) that are internal\n", - " to the main loop. \"\"\"\n", + " to the main loop. Here we calculate the total polygon area with Shoelace formula\n", + " and then determine the number of internal integer points with Pick's Theorem. \"\"\"\n", " loop_path = get_loop_path(grid, furthest, came_from) # get complete enclosed main loop\n", " logger.debug(f\"Loop path has length {len(loop_path)}.\")\n", - " pass\n", + " \n", + " area = shoelace_area(loop_path)\n", + " tiles = interior_points(area, len(loop_path))\n", + " \n", + " return tiles\n", "\n", "def d10_with_scale_up(grid: PipeGrid, furthest: Point, came_from: dict[Point, tuple]):\n", " \"\"\" Determine number of tiles (which can be empty or non-loop pipe components) that are internal\n",