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 847dacd..a3db65f 100644 --- a/src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb +++ b/src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb @@ -5091,7 +5091,6 @@ "\n", "# SETUP LOGGING\n", "logger.setLevel(logging.DEBUG)\n", - "# td.setup_file_logging(logger, locations.output_dir)\n", "\n", "# Retrieve input and store in local file\n", "try:\n", @@ -5110,7 +5109,27 @@ "source": [ "### Day 13 Part 1\n", "\n", - "We're given several 2D patterns of ash (`.`) and rocks (`#`) as input. Each pattern will have a line of symmetry, meaning that a pair of columns or a pair of rows will be identical. The line of symmetry will not necessarily be in the middle of the pattern, so we can ignore rows / columns that are not reflected.\n", + "We're given several 2D patterns of ash (`.`) and rocks (`#`) as input. Each pattern will have a line of symmetry (reflection), meaning that a pair of columns or a pair of rows will be identical. The line of symmetry will not necessarily be in the middle of the pattern, so we can ignore rows / columns that are not reflected.\n", + "\n", + "The input takes the form of many blocks, e.g.\n", + "\n", + "```text\n", + "#.##..##.\n", + "..#.##.#.\n", + "##......#\n", + "##......#\n", + "..#.##.#.\n", + "..##..##.\n", + "#.#.##.#.\n", + "\n", + "#...##..#\n", + "#....#..#\n", + "..##..###\n", + "#####.##.\n", + "#####.##.\n", + "..##..###\n", + "#....#..#\n", + "```\n", "\n", "_\"To find the reflection in each pattern, you need to find a perfect reflection across **either a horizontal line between two rows or across a vertical line between two columns.**\"_\n", "\n", @@ -5141,8 +5160,7 @@ "- This returns `True` if row `n` is identical to row `n+1`.\n", "- If the rows are identical, I then determine how many rows remain, after the symmetry line.\n", "- I then iterate through all remaining rows outwards from the symmetry line. For example, if the symmetry line were between rows 5 and 6, then the next pair of rows would be 4 and 7, then 3 and 8, and so on.\n", - "- If we get to either end of the array and all the pairs contain identical rows, then we simply return the index of the current row.\n", - "- We then add 1 to this value, to determine the number of _rows above_ or _columns before_ the symmetry line." + "- If we get to either end of the array and all the pairs contain identical rows, then we simply return the index of the current row, plus 1. We add `1` because we want the row count to include the row that was immediately left of / above the symmetry line. Thus, if the row index was `3`, then we would want the row count to be the count of rows: `0, 1, 2, 3`, i.e. `4`." ] }, { @@ -5154,17 +5172,17 @@ "def parse_patterns(data) -> list[np.ndarray]:\n", " pattern_blocks = data.split(\"\\n\\n\")\n", " return [np.array([[1 if char == '#' else 0 for char in line] \n", - " for line in block.splitlines()]) for block in pattern_blocks]\n", + " for line in block.splitlines()]) for block in pattern_blocks]\n", "\n", "def find_symmetry(array: np.ndarray, axis: int, diffs_required: int=0) -> int:\n", - " \"\"\" Find the line of symmetry, and return the count of rows or columns \n", - " before the line of symmetry.\n", + " \"\"\" Find the line of symmetry, and return the count of rows or columns before the line of symmetry.\n", " \n", " Args:\n", " array (np.ndarray): The 2D array\n", " axis (int): 0 for rows, 1 for cols\n", + " diffs_required (int): used for part 2, to allow n differences between rows. Default=0.\n", " \n", - " Returns index of row/column that is above/left of symmetry line, or -1 if no symmetry\n", + " Returns 0 if no symmetry.\n", " \"\"\"\n", " if axis == 1: # we want columns, so transpose the array\n", " array = array.T\n", @@ -5172,23 +5190,23 @@ " for row_num in range(len(array) - 1):\n", " # Compare current row with the next row\n", " diffs = np.sum(array[row_num] != array[row_num+1])\n", - " if diffs <= diffs_required:\n", + " if diffs <= diffs_required: # if no diffs, then this row is identiical to the next row\n", " rows_after = len(array) - (row_num + 2)\n", " for i in range(rows_after): # check symmetry of each remaining row\n", - " # we've run out of rows in the first half, or symmetry at first row\n", - " if row_num-i == 0: \n", + " if row_num-i == 0: # we've run out of rows in the first half, or symmetry at first row\n", " break\n", + " # For Part 1, this is sufficient:\n", " # if not np.array_equal(array[row_num-1-i], array[row_num+2+i]):\n", " diffs += np.sum(array[row_num-1-i] != array[row_num+2+i])\n", " if diffs > diffs_required:\n", " break\n", " \n", " if diffs == diffs_required:\n", - " return row_num # the row where our symmetry is\n", + " return row_num + 1 # the row count before the line of symmetry, which is equivalent to row index+1\n", " else:\n", " continue # move on to next row\n", - " \n", - " return -1 # no symmetry found\n", + " \n", + " return 0 # no symmetry found\n", " " ] }, @@ -5204,8 +5222,8 @@ " rows_above_symmetry = 0\n", " cols_left_of_symmetry = 0\n", " for pattern in patterns:\n", - " rows_above_symmetry += find_symmetry(pattern, axis=0, diffs_required=diffs_required) + 1\n", - " cols_left_of_symmetry += find_symmetry(pattern, axis=1, diffs_required=diffs_required) + 1\n", + " rows_above_symmetry += find_symmetry(pattern, axis=0, diffs_required=diffs_required) \n", + " cols_left_of_symmetry += find_symmetry(pattern, axis=1, diffs_required=diffs_required)\n", " \n", " answer = cols_left_of_symmetry + (100*rows_above_symmetry)\n", " logger.debug(f\"{rows_above_symmetry=}, {cols_left_of_symmetry=}, {answer=}\")\n", @@ -5313,7 +5331,6 @@ "\n", "```python\n", " if np.array_equal(array[row_num], array[row_num + 1]):\n", - "\n", "```\n", "\n", "We now do this:\n", @@ -5323,7 +5340,7 @@ " if diffs <= diffs_required:\n", "```\n", "\n", - "Here `np.sum()` calculates the sum of all the elements the differ between the two supplied rows.\n", + "Here `np.sum()` calculates the sum of all the elements that differ between the two supplied rows.\n", "\n", "When `diffs_required` is `0`, the result is the same as Part 1. But when `diffs_required` is `1`, this now checks for symmetry, starting with 0 or 1 differences. Then, as we check each pair of rows, we keep track of the number of differences so far.\n", "\n",