From 60ab89a2a35a1a0d6c04be51c3e0b671e47f8cef Mon Sep 17 00:00:00 2001 From: derailed-dash Date: Tue, 9 Jan 2024 22:32:16 +0000 Subject: [PATCH] Added cumulative sum solution to d11 --- .../Dazbo's_Advent_of_Code_2023.ipynb | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) 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 e4683b2..16304c1 100644 --- a/src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb +++ b/src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb @@ -4653,6 +4653,88 @@ "logger.info(f\"Soln={soln}\")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Alternative Solution\n", + "\n", + "This solution is very efficient.\n", + "\n", + "- Read in the character values into a list of lists.\n", + "- Create a cumulative sum array, to store the cumulative integer index of each row.\n", + " - For each row, if it contains a galaxy, add 1 to the sum.\n", + " - Else, add the expansion value.\n", + "- Now transpose with `zip(*grid)` and then build a col cumulative sum array in the same way.\n", + "- Now we can get the vertical distance between any pair of galaxies by obtaining the difference\n", + " of the cumulative sums of their row indexes.\n", + "- And we can get the horizontal distance between any pair of galaxies by obtaining the \n", + " differnce of the cumulative sums of their col indexes.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def solve_with_cumulative_sum(data, expansion_value:int=2):\n", + " grid = [[char for char in line] for line in data]\n", + " # logger.debug(\"\\n\" + \"\\n\".join(\"\".join(line) for line in grid))\n", + " \n", + " row_sum_array = [0] # cumulative sum of row indexes\n", + " col_sum_array = [0] # cumulative sum of col indexes\n", + " for row in grid:\n", + " add_val = expansion_value if all(char == \".\" for char in row) else 1\n", + " row_sum_array.append(row_sum_array[-1] + add_val)\n", + " \n", + " cols = list(zip(*grid)) # transpose\n", + " for col in cols:\n", + " add_val = expansion_value if all(char == \".\" for char in col) else 1\n", + " col_sum_array.append(col_sum_array[-1] + add_val)\n", + " \n", + " hash_points = set()\n", + " for y, row in enumerate(grid):\n", + " for x, char in enumerate(row):\n", + " if char == \"#\":\n", + " hash_points.add((x,y))\n", + " \n", + " shortest_paths = []\n", + " for ((ax, ay), (bx, by)) in combinations(hash_points, 2): # all combinations of 2 points\n", + " shortest_paths.append(abs(row_sum_array[by]-row_sum_array[ay]) + \n", + " abs(col_sum_array[bx]-col_sum_array[ax]))\n", + " \n", + " return sum(shortest_paths)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sample_input = \"\"\"\\\n", + "...#......\n", + ".......#..\n", + "#.........\n", + "..........\n", + "......#...\n", + ".#........\n", + ".........#\n", + "..........\n", + ".......#..\n", + "#...#.....\n", + "\"\"\"\n", + "\n", + "validate(solve_with_cumulative_sum(sample_input.splitlines(), expansion_value=2), 374) \n", + "validate(solve_with_cumulative_sum(sample_input.splitlines(), expansion_value=100), 8410) \n", + "\n", + "logger.info(\"Tests passed!\")\n", + "\n", + "logger.info(f\"Part 1 with cumulative sum={solve_with_cumulative_sum(input_data, expansion_value=2)}\")\n", + "logger.info(f\"Part 2 with cumulative sum={solve_with_cumulative_sum(input_data, expansion_value=1000000)}\")" + ] + }, { "cell_type": "markdown", "metadata": {},