From d7ff868678de81f4d3c68f22f2ccae78d9aad63f Mon Sep 17 00:00:00 2001 From: Peter Norvig Date: Tue, 9 Dec 2025 12:08:34 -0800 Subject: [PATCH] Add files via upload --- ipynb/Advent-2025-AI.ipynb | 329 ++++++++++++++++++++++++++--- ipynb/Advent-2025.ipynb | 416 ++++++++++++++++++++++++++++++++----- 2 files changed, 657 insertions(+), 88 deletions(-) diff --git a/ipynb/Advent-2025-AI.ipynb b/ipynb/Advent-2025-AI.ipynb index f5d0665..caf2abd 100644 --- a/ipynb/Advent-2025-AI.ipynb +++ b/ipynb/Advent-2025-AI.ipynb @@ -17,7 +17,7 @@ "\n", "*Each day I'll choose a model and give it the prompt* \"***Write code to solve the following problem:***\" *followed by the full text of the AoC Part 1 problem description. Then I'll prompt again with* \"***There is a change to the specification:***\" *followed by the AoC Part 2 description.*\n", "\n", - "*For brevity, I have removed some of the models' output, such as:*\n", + "*For brevity, I have removed some of the LLM output, such as:*\n", "- *Prose analysis of the problem and descriptions of the programs. (In most cases these were accurate and thorough!)*\n", "- *The \"`#!/usr/bin/env python3`\" at the top of the file*\n", "- *The \"`__main__`\" idiom for running code from the command line*\n", @@ -130,7 +130,7 @@ { "data": { "text/plain": [ - "Puzzle 1.1: .0013 seconds, answer 1182 correct" + "Puzzle 1.1: .0012 seconds, answer 1182 correct" ] }, "execution_count": 3, @@ -256,7 +256,7 @@ { "data": { "text/plain": [ - "Puzzle 1.2: .0019 seconds, answer 7509 WRONG; EXPECTED ANSWER IS 6907" + "Puzzle 1.2: .0022 seconds, answer 7509 WRONG; EXPECTED ANSWER IS 6907" ] }, "execution_count": 5, @@ -356,7 +356,7 @@ { "data": { "text/plain": [ - "Puzzle 1.2: .0016 seconds, answer 6907 correct" + "Puzzle 1.2: .0017 seconds, answer 6907 correct" ] }, "execution_count": 7, @@ -436,7 +436,7 @@ { "data": { "text/plain": [ - "Puzzle 2.1: .1247 seconds, answer 23560874270 correct" + "Puzzle 2.1: .1217 seconds, answer 23560874270 correct" ] }, "execution_count": 9, @@ -520,7 +520,7 @@ { "data": { "text/plain": [ - "Puzzle 2.2: .1325 seconds, answer 44143124633 correct" + "Puzzle 2.2: .1282 seconds, answer 44143124633 correct" ] }, "execution_count": 11, @@ -591,7 +591,7 @@ { "data": { "text/plain": [ - "Puzzle 3.1: .0042 seconds, answer 17085 correct" + "Puzzle 3.1: .0038 seconds, answer 17085 correct" ] }, "execution_count": 13, @@ -674,7 +674,7 @@ { "data": { "text/plain": [ - "Puzzle 3.2: .0078 seconds, answer 169408143086082 correct" + "Puzzle 3.2: .0069 seconds, answer 169408143086082 correct" ] }, "execution_count": 15, @@ -767,7 +767,7 @@ { "data": { "text/plain": [ - "Puzzle 4.1: .0182 seconds, answer 1569 correct" + "Puzzle 4.1: .0170 seconds, answer 1569 correct" ] }, "execution_count": 17, @@ -860,7 +860,7 @@ { "data": { "text/plain": [ - "Puzzle 4.2: .3946 seconds, answer 9280 correct" + "Puzzle 4.2: .3880 seconds, answer 9280 correct" ] }, "execution_count": 19, @@ -969,7 +969,7 @@ { "data": { "text/plain": [ - "Puzzle 4.2: .0938 seconds, answer 9280 correct" + "Puzzle 4.2: .0874 seconds, answer 9280 correct" ] }, "execution_count": 21, @@ -1063,7 +1063,7 @@ { "data": { "text/plain": [ - "Puzzle 5.1: .0056 seconds, answer 635 correct" + "Puzzle 5.1: .0053 seconds, answer 635 correct" ] }, "execution_count": 23, @@ -1278,7 +1278,7 @@ { "data": { "text/plain": [ - "Puzzle 6.1: .0078 seconds, answer 5877594983578 correct" + "Puzzle 6.1: .0079 seconds, answer 5877594983578 correct" ] }, "execution_count": 27, @@ -1414,7 +1414,7 @@ { "data": { "text/plain": [ - "Puzzle 6.2: .0070 seconds, answer 11159825706149 correct" + "Puzzle 6.2: .0064 seconds, answer 11159825706149 correct" ] }, "execution_count": 29, @@ -1798,7 +1798,7 @@ { "data": { "text/plain": [ - "Puzzle 7.2: .0022 seconds, answer 422102272495018 correct" + "Puzzle 7.2: .0024 seconds, answer 422102272495018 correct" ] }, "execution_count": 36, @@ -1938,7 +1938,7 @@ { "data": { "text/plain": [ - "Puzzle 8.1: .8993 seconds, answer 24360 correct" + "Puzzle 8.1: .8309 seconds, answer 24360 correct" ] }, "execution_count": 38, @@ -2077,7 +2077,7 @@ { "data": { "text/plain": [ - "Puzzle 8.2: .8707 seconds, answer 2185817796 correct" + "Puzzle 8.2: .8300 seconds, answer 2185817796 correct" ] }, "execution_count": 40, @@ -2090,6 +2090,267 @@ " solve_part2(boxes))" ] }, + { + "cell_type": "markdown", + "id": "c6db8a6e-47bf-490f-a54c-6472b4f935a0", + "metadata": {}, + "source": [ + "# [Day 9](https://adventofcode.com/2025/day/9): ChatGPT 5.1 Auto\n", + "\n", + "*For **Part 1**, ChatGPT wrote a `main` program that reads from input and prints the answer. I told it **Refactor to have a function that takes the points as input and returns the area** and got this:*" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "aaf6b9df-b55d-4416-b806-167ad3b70fd5", + "metadata": {}, + "outputs": [], + "source": [ + "def largest_rectangle_area(points):\n", + " \"\"\"\n", + " Given a list of (x, y) points representing red tiles,\n", + " return the largest possible rectangle area using any\n", + " two points as opposite corners.\n", + " \"\"\"\n", + " max_area = 0\n", + " n = len(points)\n", + "\n", + " for i in range(n):\n", + " x1, y1 = points[i]\n", + " for j in range(i + 1, n):\n", + " x2, y2 = points[j]\n", + "\n", + " width = abs(x2 - x1) + 1\n", + " height = abs(y2 - y1) + 1\n", + " area = width * height\n", + "\n", + " if area > max_area:\n", + " max_area = area\n", + "\n", + " return max_area\n" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "352cb801-67d7-4aaf-b0a1-1a59c1990c22", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Puzzle 9.1: .0282 seconds, answer 4772103936 correct" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "points = parse(9, ints, show=0)\n", + "\n", + "answer(9.1, 4772103936, lambda:\n", + " largest_rectangle_area(points))" + ] + }, + { + "cell_type": "markdown", + "id": "5f8a09ab-0d49-4a6b-b8ea-33e4219af1eb", + "metadata": {}, + "source": [ + "*For **Part 2**, ChatGPT considered a [scanline algorithm](https://en.wikipedia.org/wiki/Scanline_rendering), and then went for a [flood fill](https://en.wikipedia.org/wiki/Flood_fill). It assumed \"I'm working with a grid that can have dimensions up to 2k x 2k, or 4 million cells, which seems manageable.\" So I told it **The grid can have dimensions up to 100,000 x 100,000 and there are about 500 red tile points**. ChatGPT came up with a [grid compression](https://stackoverflow.com/questions/29528934/coordinate-compression) method: define a grid where each red tile is in a separate cell, where the x and y extent of that cell spans an integer range (which must be recorded elsewhere). Now the grid is only of size roughly 5002 instead of 100,0002." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "16aa5c15-e5d5-4652-83d8-d99da9196617", + "metadata": {}, + "outputs": [], + "source": [ + "from typing import List, Tuple, Dict\n", + "\n", + "Point = Tuple[int, int]\n", + "Edge = Tuple[int, int, int, int]\n", + "\n", + "\n", + "def build_edges(points: List[Point]) -> List[Edge]:\n", + " \"\"\"\n", + " Build polygon edges from the red points in loop order.\n", + " Each edge is (x1, y1, x2, y2) between consecutive points (wrapped).\n", + " \"\"\"\n", + " n = len(points)\n", + " edges: List[Edge] = []\n", + " for i in range(n):\n", + " x1, y1 = points[i]\n", + " x2, y2 = points[(i + 1) % n]\n", + " edges.append((x1, y1, x2, y2))\n", + " return edges\n", + "\n", + "\n", + "def point_in_or_on_polygon(x: int, y: int, edges: List[Edge]) -> bool:\n", + " \"\"\"\n", + " Return True if lattice point (x, y) is inside the polygon or on its boundary.\n", + " Polygon is rectilinear (axis-aligned), edges given by build_edges.\n", + " Uses a ray-casting test along +x, counting intersections with vertical edges.\n", + " \"\"\"\n", + " inside = False\n", + "\n", + " for (x1, y1, x2, y2) in edges:\n", + " # Boundary check: point lies on this edge\n", + " if x1 == x2: # vertical edge\n", + " if x == x1 and min(y1, y2) <= y <= max(y1, y2):\n", + " return True\n", + " # For ray cast, only vertical edges can intersect ray to +x\n", + " # Use y-interval [min, max) to avoid double-counting vertices\n", + " if (y1 > y) != (y2 > y) and x1 > x:\n", + " inside = not inside\n", + " else: # horizontal edge\n", + " if y == y1 and min(x1, x2) <= x <= max(x1, x2):\n", + " return True\n", + " # horizontal edges do not contribute to this vertical ray count\n", + "\n", + " return inside\n", + "\n", + "\n", + "def rect_crosses_polygon(\n", + " xmin: int, xmax: int, ymin: int, ymax: int, edges: List[Edge]\n", + ") -> bool:\n", + " \"\"\"\n", + " For a non-degenerate rectangle [xmin,xmax] x [ymin,ymax] (width>1,height>1),\n", + " check if any polygon edge passes through the *interior* of that rectangle.\n", + " Colinear edges on the boundary are allowed; only crossings inside are bad.\n", + " \"\"\"\n", + " for (x1, y1, x2, y2) in edges:\n", + " if x1 == x2:\n", + " # vertical edge at x = x1\n", + " x0 = x1\n", + " if xmin < x0 < xmax:\n", + " lo = max(min(y1, y2), ymin)\n", + " hi = min(max(y1, y2), ymax)\n", + " # If overlap has positive length, edge crosses interior\n", + " if hi > lo:\n", + " return True\n", + " else:\n", + " # horizontal edge at y = y1\n", + " y0 = y1\n", + " if ymin < y0 < ymax:\n", + " lo = max(min(x1, x2), xmin)\n", + " hi = min(max(x1, x2), xmax)\n", + " if hi > lo:\n", + " return True\n", + " return False\n", + "\n", + "\n", + "def largest_rectangle_area_red_green(points: List[Point]) -> int:\n", + " \"\"\"\n", + " Given the red tiles as vertices of an axis-aligned loop (in order),\n", + " return the largest rectangle area such that:\n", + "\n", + " - Two opposite corners are red tiles (from `points`).\n", + " - Every tile inside the rectangle is red or green, i.e., inside/on the loop.\n", + "\n", + " This works without building the full grid; it uses polygon geometry instead.\n", + " \"\"\"\n", + " n = len(points)\n", + " if n < 2:\n", + " return 0\n", + "\n", + " edges = build_edges(points)\n", + "\n", + " # Cache point-in-polygon results so each lattice point is tested at most once\n", + " point_cache: Dict[Point, bool] = {}\n", + "\n", + " def is_inside(x: int, y: int) -> bool:\n", + " key = (x, y)\n", + " if key in point_cache:\n", + " return point_cache[key]\n", + " val = point_in_or_on_polygon(x, y, edges)\n", + " point_cache[key] = val\n", + " return val\n", + "\n", + " max_area = 0\n", + "\n", + " for i in range(n):\n", + " x1, y1 = points[i]\n", + " for j in range(i + 1, n):\n", + " x2, y2 = points[j]\n", + "\n", + " xmin, xmax = (x1, x2) if x1 <= x2 else (x2, x1)\n", + " ymin, ymax = (y1, y2) if y1 <= y2 else (y2, y1)\n", + "\n", + " width = xmax - xmin + 1 # tiles\n", + " height = ymax - ymin + 1 # tiles\n", + " area = width * height\n", + "\n", + " if area <= max_area:\n", + " continue\n", + "\n", + " # Thin rectangles (one row or one column): treat as 1D segments.\n", + " if width == 1 or height == 1:\n", + " if width == 1:\n", + " # Vertical segment at x = xmin from ymin..ymax\n", + " x = xmin\n", + " ok = True\n", + " for yy in range(ymin, ymax + 1):\n", + " if not is_inside(x, yy):\n", + " ok = False\n", + " break\n", + " else:\n", + " # Horizontal segment at y = ymin from xmin..xmax\n", + " y = ymin\n", + " ok = True\n", + " for xx in range(xmin, xmax + 1):\n", + " if not is_inside(xx, y):\n", + " ok = False\n", + " break\n", + "\n", + " if ok:\n", + " max_area = area\n", + " continue\n", + "\n", + " # Proper 2D rectangle: width>1 and height>1\n", + "\n", + " # The two given red corners are on the boundary by definition.\n", + " # The other two corners must be inside/on polygon as well.\n", + " if not is_inside(x1, y2):\n", + " continue\n", + " if not is_inside(x2, y1):\n", + " continue\n", + "\n", + " # Ensure polygon boundary does not cut through the interior\n", + " if rect_crosses_polygon(xmin, xmax, ymin, ymax, edges):\n", + " continue\n", + "\n", + " max_area = area\n", + "\n", + " return max_area" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "3388880d-6df9-4453-8b54-43175e3077e2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Puzzle 9.2: .7622 seconds, answer 1529675217 correct" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "answer(9.2, 1529675217, lambda:\n", + " largest_rectangle_area_red_green(points))" + ] + }, { "cell_type": "markdown", "id": "8aa26008-a652-4860-9c84-5ba4344d32f3", @@ -2102,7 +2363,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 45, "id": "16ce8af4-a1da-4280-9078-116ced3e9941", "metadata": {}, "outputs": [ @@ -2110,24 +2371,26 @@ "name": "stdout", "output_type": "stream", "text": [ - "Puzzle 1.1: .0013 seconds, answer 1182 correct\n", - "Puzzle 1.2: .0016 seconds, answer 6907 correct\n", - "Puzzle 2.1: .1247 seconds, answer 23560874270 correct\n", - "Puzzle 2.2: .1325 seconds, answer 44143124633 correct\n", - "Puzzle 3.1: .0042 seconds, answer 17085 correct\n", - "Puzzle 3.2: .0078 seconds, answer 169408143086082 correct\n", - "Puzzle 4.1: .0182 seconds, answer 1569 correct\n", - "Puzzle 4.2: .0938 seconds, answer 9280 correct\n", - "Puzzle 5.1: .0056 seconds, answer 635 correct\n", + "Puzzle 1.1: .0012 seconds, answer 1182 correct\n", + "Puzzle 1.2: .0017 seconds, answer 6907 correct\n", + "Puzzle 2.1: .1217 seconds, answer 23560874270 correct\n", + "Puzzle 2.2: .1282 seconds, answer 44143124633 correct\n", + "Puzzle 3.1: .0038 seconds, answer 17085 correct\n", + "Puzzle 3.2: .0069 seconds, answer 169408143086082 correct\n", + "Puzzle 4.1: .0170 seconds, answer 1569 correct\n", + "Puzzle 4.2: .0874 seconds, answer 9280 correct\n", + "Puzzle 5.1: .0053 seconds, answer 635 correct\n", "Puzzle 5.2: .0002 seconds, answer 369761800782619 correct\n", - "Puzzle 6.1: .0078 seconds, answer 5877594983578 correct\n", - "Puzzle 6.2: .0070 seconds, answer 11159825706149 correct\n", + "Puzzle 6.1: .0079 seconds, answer 5877594983578 correct\n", + "Puzzle 6.2: .0064 seconds, answer 11159825706149 correct\n", "Puzzle 7.1: .0009 seconds, answer 1681 correct\n", - "Puzzle 7.2: .0022 seconds, answer 422102272495018 correct\n", - "Puzzle 8.1: .8993 seconds, answer 24360 correct\n", - "Puzzle 8.2: .8707 seconds, answer 2185817796 correct\n", + "Puzzle 7.2: .0024 seconds, answer 422102272495018 correct\n", + "Puzzle 8.1: .8309 seconds, answer 24360 correct\n", + "Puzzle 8.2: .8300 seconds, answer 2185817796 correct\n", + "Puzzle 9.1: .0282 seconds, answer 4772103936 correct\n", + "Puzzle 9.2: .7622 seconds, answer 1529675217 correct\n", "\n", - "Time in seconds: sum = 2.178, mean = .136, median = .007, max = .899\n" + "Time in seconds: sum = 2.842, mean = .158, median = .007, max = .831\n" ] } ], diff --git a/ipynb/Advent-2025.ipynb b/ipynb/Advent-2025.ipynb index 6883196..1b6b0d7 100644 --- a/ipynb/Advent-2025.ipynb +++ b/ipynb/Advent-2025.ipynb @@ -17,7 +17,7 @@ "\n", "I'm glad that [@GaryGrady](https://mastodon.social/@garygrady) is providing cartoons:\n", "\n", - "\"Gary\n", + "\"Gary\n", "\n", "I start by loading up my [**AdventUtils.ipynb**](AdventUtils.ipynb) notebook (same as last time except for the `current_year`). On each day I will first parse the input (with the help of my `parse` utility function), then solve Part 1 and Part 2 (recording the correct answer with my `answer` function)." ] @@ -40,7 +40,7 @@ "source": [ "# [Day 1](https://adventofcode.com/2025/day/1): Secret Entrance\n", "\n", - "On Day 1 we meet an elf and learn that our task is to finish decorating the North Pole by December 12th. There will be 24 challenges along the way. Today we need to unlock a safe. The safe has a dial with 100 numbers. Our input for today is a sequence of left and right rotations; for example \"R20\" means move the dial right by 20 numbers and \"L13\" means move it left by 13 numbers. I'll use my `parse` utility function to parse each line of the input as an integer, after replacing each 'L' with a minus sign and each 'R' with a plus sign:" + "On Day 1 we meet an elf and learn that our task is to finish decorating the North Pole by December 12th. There will be 24 challenges along the way; the first one involves unlocking a safe. The safe has a dial with 100 numbers, and an arrow that currently points at 50. Our input for today is a sequence of left and right rotations; for example \"R20\" means move the dial right by 20 numbers and \"L13\" means move it left by 13 numbers. I'll use my `parse` utility function to parse each line of the input as an integer, after replacing each 'L' with a minus sign and each 'R' with a plus sign:" ] }, { @@ -66,7 +66,7 @@ "L48\n", "...\n", "────────────────────────────────────────────────────────────────────────────────────────────────────\n", - "Parsed representation ➜ 4780 ints:\n", + "Parsed representation ➜ 4780 ints in range -999 to 997:\n", "────────────────────────────────────────────────────────────────────────────────────────────────────\n", "-20\n", "-13\n", @@ -97,7 +97,7 @@ "\n", "### Part 1: How many times is the dial left pointing at 0 after any rotation in the sequence?\n", "\n", - "Initially the safe's arrow is pointing at 50, and then we apply the rotations in order. We are asked how many of the rotations leave the dial pointing at 0. The `itertools.accumulate` function yields running totals of its input sequence, so we just have to count (quantify) how many times the running total of the rotations is 0 mod 100. I'll write a function to do that and run it on the input:" + "When applying the rotations in order, we are asked how many of the rotations leave the dial pointing at 0. The `itertools.accumulate` function yields running totals of its input sequence, so we just have to count (quantify) how many times the running total of the rotations is 0 mod 100. I'll write a function to do that and run it on the input:" ] }, { @@ -138,7 +138,7 @@ "id": "b5f68a70-8465-4249-954c-cba2b78751d8", "metadata": {}, "source": [ - "I submitted \"1182\" to AoC and saw it was correct, so I record the `answer` like this:" + "I submitted \"1182\" to AoC and got back *That's the right answer!*, so I record the answer (and its run time) like this:" ] }, { @@ -150,7 +150,7 @@ { "data": { "text/plain": [ - "Puzzle 1.1: .0006 seconds, answer 1182 correct" + "Puzzle 1.1: .0007 seconds, answer 1182 correct" ] }, "execution_count": 5, @@ -170,9 +170,9 @@ "source": [ "### Part 2: How many times does the dial point to 0 at any time?\n", "\n", - "For Part 2 we need to count both when a rotation ends up at 0 and when the arrow passes 0 at any time during a rotation. For example, if the arrow points to 95, then only a \"R5\" or a \"L95\" would register a 0 in Part 1, but now a rotation of \"R10\" would also count because it passes 0 (as would any rotation of \"R5\" or larger, or \"L95\" or larger). \n", + "For Part 2 we are asked to count both when a rotation ends up at 0 and when the arrow passes 0 at any time during a rotation. For example, if the arrow points to 95, then only a \"R5\" or a \"L95\" would register a 0 in Part 1, but now for Part 2 a rotation of \"R10\" would also count because it passes 0 (as would any rotation of \"R5\" or larger, or \"L95\" or larger). \n", "\n", - "I'll start with a simple but slow approach: treat a rotation of, say, -20 as 20 rotations of -1, and then use the same `count_zeros` function from part 1. (Note that `sign(r)` returns +1 for any positive input, and -1 for any negative input.)" + "I'll start with a brute force approach: treat a rotation of, say, 20 as 20 rotations of 1, and then use the same `count_zeros` function from Part 1. (Note that `sign(r)` returns +1 for any positive input, and -1 for any negative input.)" ] }, { @@ -184,7 +184,7 @@ { "data": { "text/plain": [ - "Puzzle 1.2: .1367 seconds, answer 6907 correct" + "Puzzle 1.2: .1370 seconds, answer 6907 correct" ] }, "execution_count": 6, @@ -202,7 +202,7 @@ "id": "bb0f6906-369e-4b3c-8840-d5648d713942", "metadata": {}, "source": [ - "That's a long run time for a Day 1 problem, so here's a faster method: I break each rotation down into a number of full circles and some remainder, then add the full circles to the count of zeros, and add one more if the remainder is at least as much as the distance to zero (in the appropriate direction): " + "That's a long run time for a Day 1 problem, so here's a faster method: break each rotation down into a number of full circles and some remainder, then add the full circles to the count of zeros, and add one more if the remainder is at least as much as the distance to zero (in the appropriate direction): " ] }, { @@ -234,7 +234,7 @@ { "data": { "text/plain": [ - "Puzzle 1.2: .0009 seconds, answer 6907 correct" + "Puzzle 1.2: .0010 seconds, answer 6907 correct" ] }, "execution_count": 8, @@ -252,7 +252,7 @@ "id": "f47b1f7a-c9d9-4b21-a28a-f1e4e73d4c0d", "metadata": {}, "source": [ - "That's much faster, but the code is trickier, and indeed I initially had a **bug** in the `distance_to_0` computation: when the current position is 0 the distance should be 100: it takes a full rotation to get back to 0. My code initially claimed the distance was 0; adding `or position == 0` fixed that." + "That's much faster, but the code is trickier, and indeed I initially had a **bug** in the `distance_to_0` computation: when the current position is 0 the distance should be 100: it takes a full rotation to get back to 0. I fixed the bug by adding `or position == 0`." ] }, { @@ -379,7 +379,7 @@ { "data": { "text/plain": [ - "Puzzle 2.1: .0029 seconds, answer 23560874270 correct" + "Puzzle 2.1: .0030 seconds, answer 23560874270 correct" ] }, "execution_count": 12, @@ -463,7 +463,7 @@ { "data": { "text/plain": [ - "Puzzle 2.1: .0032 seconds, answer 23560874270 correct" + "Puzzle 2.1: .0029 seconds, answer 23560874270 correct" ] }, "execution_count": 15, @@ -485,7 +485,7 @@ { "data": { "text/plain": [ - "Puzzle 2.2: .0037 seconds, answer 44143124633 correct" + "Puzzle 2.2: .0043 seconds, answer 44143124633 correct" ] }, "execution_count": 16, @@ -503,7 +503,7 @@ "id": "872cf212-bfbf-4edd-b898-5f76ad122a85", "metadata": {}, "source": [ - "I initially had another **bug** here: I counted \"222222\" three times: once as 2 repeats of \"222\", once as 3 repeats of \"22\", and once as 6 repeats of \"2\". I changed the output of `all_invalids` to be a `set` to fix that." + "I initially had another **bug** here: I initially counted \"222222\" three times: once as 2 repeats of \"222\", once as 3 repeats of \"22\", and once as 6 repeats of \"2\". I changed the output of `all_invalids` to be a `set` rather than a `list` to fix that." ] }, { @@ -594,7 +594,7 @@ { "data": { "text/plain": [ - "Puzzle 3.1: .0007 seconds, answer 17085 correct" + "Puzzle 3.1: .0006 seconds, answer 17085 correct" ] }, "execution_count": 20, @@ -713,7 +713,7 @@ "source": [ "# [Day 4](https://adventofcode.com/2025/day/4): Printing Department\n", "\n", - "The floor of the printing department is divided into squares, some of which contain a roll of paper. The day's input is a map of the floor, with `@` representing a roll of paper. I can handle that with the `Grid` class from my AdventUtils:" + "The floor of the printing department is divided into squares, some of which contain a roll of paper. The day's input is a map of the floor, with `@` representing a roll of paper. I can handle that with the `Grid` class from my [AdventUtils](AdventUtils.ipynb):" ] }, { @@ -792,7 +792,7 @@ { "data": { "text/plain": [ - "Puzzle 4.1: .0527 seconds, answer 1569 correct" + "Puzzle 4.1: .0511 seconds, answer 1569 correct" ] }, "execution_count": 27, @@ -826,7 +826,7 @@ "source": [ "def removable_rolls(grid: Grid) -> Iterable[Point]:\n", " \"\"\"The positions of paper rolls that can be removed, in any nuber of iterations.\"\"\"\n", - " grid2 = grid.copy() # To avoid mutating the input grid\n", + " grid2 = grid.copy() # To avoid mutating the original input grid\n", " points = accessible_rolls(grid2)\n", " while points:\n", " yield from points\n", @@ -843,7 +843,7 @@ { "data": { "text/plain": [ - "Puzzle 4.2: 1.2384 seconds, answer 9280 correct" + "Puzzle 4.2: 1.2270 seconds, answer 9280 correct" ] }, "execution_count": 29, @@ -892,7 +892,7 @@ { "data": { "text/plain": [ - "Puzzle 4.2: .1424 seconds, answer 9280 correct" + "Puzzle 4.2: .1380 seconds, answer 9280 correct" ] }, "execution_count": 31, @@ -912,7 +912,7 @@ "source": [ "# [Day 5](https://adventofcode.com/2025/day/5): Cafeteria\n", "\n", - "Today we're in the cafeteria, and the elves need to figure out which of their ingredients are fresh or spoiled. The input file has two parts (paragraphs), the first consisting of ranges of fresh ingredient IDs, like \"3-5\" and the second consisting of the available ingredient IDs, like \"8\". I can parse the data like this:" + "Today we're in the cafeteria, and the elves need to figure out which of their ingredients are fresh or spoiled. The input file has two parts (paragraphs), the first consisting of ranges of fresh ingredient IDs, like \"6-7\" and the second consisting of the available ingredient IDs, like \"8\". I can parse the data like this:" ] }, { @@ -948,6 +948,8 @@ "source": [ "def parse_ingredients(text: str) -> tuple:\n", " \"\"\"Parse either ranges like \"3-5\", or integers like \"8\".\"\"\"\n", + " if '-' in text:\n", + " return mapt(positive_ints, lines(text))\n", " return mapt(positive_ints, lines(text)) if '-' in text else ints(text)\n", " \n", "fresh_ranges, available_ingredient_ids = parse(day=5, parser=parse_ingredients, sections=paragraphs)" @@ -985,7 +987,7 @@ { "data": { "text/plain": [ - "Puzzle 5.1: .0079 seconds, answer 635 correct" + "Puzzle 5.1: .0072 seconds, answer 635 correct" ] }, "execution_count": 34, @@ -1233,7 +1235,7 @@ { "data": { "text/plain": [ - "Puzzle 6.2: .0039 seconds, answer 11159825706149 correct" + "Puzzle 6.2: .0038 seconds, answer 11159825706149 correct" ] }, "execution_count": 42, @@ -1479,7 +1481,7 @@ { "data": { "text/plain": [ - "Puzzle 7.2: .0014 seconds, answer 422102272495018 correct" + "Puzzle 7.2: .0015 seconds, answer 422102272495018 correct" ] }, "execution_count": 51, @@ -1504,14 +1506,6 @@ " count_timelines(manifold))" ] }, - { - "cell_type": "markdown", - "id": "ed2369ae-cf37-4b12-9933-4bfe95fec3ac", - "metadata": {}, - "source": [ - "\"Gary" - ] - }, { "cell_type": "markdown", "id": "135b532d-d9ac-4400-9c6d-3b316d4596e1", @@ -1568,11 +1562,13 @@ "id": "ee9f47ae-09f5-479e-9e34-34246d723952", "metadata": {}, "source": [ + "\"Gary\n", + "\n", "### Part 1: What is the product of the sizes of the three largest circuits?\n", "\n", - "The goal is to start connecting junction boxes, starting with the two boxes that are closest to each other in 3D space, then the next two closest, and so on. (I assume that a box can connect to any number of other boxes.) After connecting the 1000 pairs that are closest together, what do you get if you multiply together the sizes of the three largest circuits?\n", + "The goal is to start connecting junction boxes, starting with the two boxes that are closest to each other in 3D space, then the next two closest, and so on. (I assume that a box can connect to an unlimited number of other boxes.) After connecting the 1000 pairs that are closest together, what do you get if you multiply together the sizes of the three largest circuits?\n", "\n", - "I recognize this as a [**greedy algorithm**](https://en.wikipedia.org/wiki/Greedy_algorithm), consuming shortest links first, and I've [done that before](TSP.ipynb). I also recognize this as a [**Union-Find**](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) problem, and I know there are efficient data structures for that problem we don't make heavy use of the union-find functionality, so keeping it simple seems to be the best result. (After finishing my code I feel vindicated: I see in my [other notebook](Advent2025-AI.ipynb) that Claude Opus 4.5 also recognized the Union-Find problem, implemented a data structure for it, and ended up with code that ran slower than my simpler approach.)\n", + "I recognize this as a [**greedy algorithm**](https://en.wikipedia.org/wiki/Greedy_algorithm), consuming shortest links first, and I've [done that before](TSP.ipynb). I also recognize this as a [**Union-Find**](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) problem, and I know there are efficient data structures for that problem. However, for this problem we don't make heavy use of the union-find functionality, so keeping it simple seems to be the best result. (After finishing my code I feel vindicated: I see in my [other notebook](Advent2025-AI.ipynb) that Claude Opus 4.5 implemented a Union-Find data structure, and ended up with code that ran slower than my simpler approach.)\n", "\n", "The function `greedy_connect` will keep a dict that maps each box to the circuit it is part of (initially just itself), and update that dict when two circuits are connected together. Then I'll go through the 1000 `closest_pairs` of boxes, updating the dict for each one, and return the dict at the end. Then the function `largest` will find the largest 3 circuits, and `prod` will multiply the sizes together." ] @@ -1619,7 +1615,7 @@ { "data": { "text/plain": [ - "Puzzle 8.1: .6207 seconds, answer 24360 correct" + "Puzzle 8.1: .5863 seconds, answer 24360 correct" ] }, "execution_count": 54, @@ -1637,9 +1633,9 @@ "id": "3291fa28-a8fa-4ef8-90b3-2b4b6fc9625e", "metadata": {}, "source": [ - "### Part 2: What do you get if you multiply together the X coordinates of the last two junction boxes you need to connect?\n", + "### Part 2: What is the product of the X coordinates of the last two junction boxes connected?\n", "\n", - "Now we are asked for the product of the X coordinates of the final pair of boxes to be connected. Unfortunately I'll have to copy and paste most of `greedy_connect` to form `last_connected`, which checks to see if all the boxes are connected into one circuit, and if so returns the two boxes that made the final connection. " + "Now we are asked to connect all the boxes into one circuit, still closest first, and compute the product of the X coordinates of the final pair of boxes to be connected. Unfortunately I don't see a way to make `greedy_connect` do both parts; I'll have to copy and paste most of `greedy_connect` to form `last_connected`, which keeps connecting until all the boxes are connected into one circuit, and then returns the two boxes that made the final connection. " ] }, { @@ -1649,11 +1645,11 @@ "metadata": {}, "outputs": [], "source": [ - "def last_connected(boxes) -> dict:\n", + "def last_connected(boxes) -> Tuple[Point, Point]:\n", " \"\"\"Go through tall the pairs of boxes, in closest first order. \n", " Return the last two boxes that finally make it all one big circuit.\"\"\"\n", " circuits = {B: (B,) for B in boxes} # A dict of {box: circuit}\n", - " for (A, B) in closest_pairs(boxes, -1):\n", + " for (A, B) in closest_pairs(boxes, len(boxes) ** 2):\n", " if circuits[A] != circuits[B]:\n", " new_circuit = circuits[A] + circuits[B]\n", " if len(new_circuit) == len(boxes):\n", @@ -1671,7 +1667,7 @@ { "data": { "text/plain": [ - "Puzzle 8.2: .6530 seconds, answer 2185817796 correct" + "Puzzle 8.2: .6265 seconds, answer 2185817796 correct" ] }, "execution_count": 56, @@ -1692,6 +1688,314 @@ "Today's puzzles had the slowest run times yet. I could perhaps make them faster by mutating sets rather than forming a new tuple for each new circuit, but I think gains from that would be small, and since the run time is still under a second, I'll leave the code as is." ] }, + { + "cell_type": "markdown", + "id": "9e75bcf2-d62b-47b1-bec0-b2449351d819", + "metadata": {}, + "source": [ + "# [Day 9](https://adventofcode.com/2025/day/9): Movie Theater \n", + "\n", + "The Elves are redecorating the movie theater floor by switching out some of the square tiles in the big grid they form. Some of the tiles are red; their coordinates form the day's input file:" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "2dba6fa4-a09b-4ab3-a163-0f94f98e82f2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "────────────────────────────────────────────────────────────────────────────────────────────────────\n", + "Puzzle input ➜ 496 strs of size 10 to 11:\n", + "────────────────────────────────────────────────────────────────────────────────────────────────────\n", + "98214,50351\n", + "98214,51580\n", + "98424,51580\n", + "98424,52775\n", + "97835,52775\n", + "97835,54031\n", + "98280,54031\n", + "98280,55255\n", + "...\n", + "────────────────────────────────────────────────────────────────────────────────────────────────────\n", + "Parsed representation ➜ 496 tuples of size 2:\n", + "────────────────────────────────────────────────────────────────────────────────────────────────────\n", + "(98214, 50351)\n", + "(98214, 51580)\n", + "(98424, 51580)\n", + "(98424, 52775)\n", + "(97835, 52775)\n", + "(97835, 54031)\n", + "(98280, 54031)\n", + "(98280, 55255)\n", + "...\n" + ] + } + ], + "source": [ + "red_tiles = parse(9, ints)" + ] + }, + { + "cell_type": "markdown", + "id": "f8d3b123-234d-41b9-bb5b-090ad1b11e78", + "metadata": {}, + "source": [ + "### Part 1: What is the largest area of any rectangle you can make?\n", + "\n", + "The Elves would like to find the largest rectangle that uses red tiles for two of its opposite corners. That's easy; we can try all combinations of two corners and take the corners with the maximum area. The only tricky part is remembering that we have to add one to the delta-x and delta-y numbers before multiplying them; the area of a square with coreners (0, 0) and (0, 1) is 4 tiles, not 1." + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "75f2742e-9dbd-4005-a882-3d3931fb1b36", + "metadata": {}, + "outputs": [], + "source": [ + "def tile_area(corners: Tuple[Point, Point]):\n", + " \"\"\"Area, in tiles, of a rectangle formed by tiles at these corner positions.\"\"\"\n", + " (x1, y1), (x2, y2) = corners\n", + " return (abs(x1 - x2) + 1) * (abs(y1 - y2) + 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "27f350c5-7866-4b7b-8d32-91512fcec5b9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Puzzle 9.1: .0285 seconds, answer 4772103936 correct" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "answer(9.1, 4772103936, lambda:\n", + " max(map(tile_area, combinations(red_tiles, 2))))" + ] + }, + { + "cell_type": "markdown", + "id": "dbd4e094-109f-420c-90b9-0ada15b1da9d", + "metadata": {}, + "source": [ + "### Part 2: What is the largest area of any rectangle you can make using only red and green tiles?\n", + "\n", + "Now we find that there are also green tiles. Every red tile is connected to the red tile before and after it (in the input list) by a straight line of green tiles. The list wraps, so the first red tile is also connected to the last red tile. This forms a closed figure, and the interior of the figure is all green. The outside of the figure, I'm guessing, is all white tiles. The elves want to know: What is the largest area of any rectangle you can make using only red and green tiles?\n", + "\n", + "This is a tough one! There are only 496 red tiles, so enumerating all pairs of them was easy. But there are roughly 100,0002 = 10,000,000,000 total tiles, so enumerating them would be too slow. To get some ideas, I really want to see what the red tiles look like:" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "id": "b5967a65-338d-4198-9f59-986ff74132e6", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.axis('equal')\n", + "plt.plot(*T(red_tiles), 'r.-');" + ] + }, + { + "cell_type": "markdown", + "id": "bd58135d-4ed6-4a5c-866e-864e850d31cb", + "metadata": {}, + "source": [ + "**Interesting!** A maximal-area rectangle can't cross the equator lines. It seems clear that one of the corners of the maximal rectangle has to be one of the two points on the right side of the equator lines, and the other corner has to be somewhere in either the upper left or lower left. I could split the puzzle in half and try to find those left-side corners. Here's how to split the tiles:" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "4679e2de-15a0-408a-a3d9-6feb3eddd66a", + "metadata": {}, + "outputs": [], + "source": [ + "Corners = Tuple[Point, Point] # Type representing the corners of a rectangle\n", + "\n", + "def split_tiles(red_tiles, d=60000) -> Tuple[List[Point], List[Point], Corners]:\n", + " \"\"\"Split the tiles into top and bottom halves, and also return the two right-side corners.\"\"\"\n", + " for i in range(len(red_tiles)):\n", + " if distance(red_tiles[i], red_tiles[i + 1]) > d:\n", + " return red_tiles[:i+2], red_tiles[i+2:], red_tiles[i+1:i+3],\n", + "\n", + "def split_tiles(red_tiles, d=60000) -> Tuple[List[Point], List[Point], Corners]:\n", + " \"\"\"Split the tiles into top and bottom halves, and also return the two right-side corners.\"\"\"\n", + " i = max(range(-1, len(red_tiles) - 1), key=lambda i: distance(red_tiles[i], red_tiles[i + 1]))\n", + " return red_tiles[:i+2], red_tiles[i+2:], red_tiles[i+1:i+3]," + ] + }, + { + "cell_type": "markdown", + "id": "7829d2cd-2818-4201-8b11-46d571037353", + "metadata": {}, + "source": [ + "And here's what it looks like:" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "id": "f1c1f29f-7981-42de-bcab-d2aedb8a9613", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "top, bot, corners = split_tiles(red_tiles)\n", + "\n", + "plt.axis('equal')\n", + "plt.plot(*T(top), 'r.-') # Top half red\n", + "plt.plot(*T(bot), 'y.-') # Bottom half yellow\n", + "plt.plot(*T(corners), 'bo'); # Corner points blue" + ] + }, + { + "cell_type": "markdown", + "id": "24c97571-1b76-4bf7-a1e7-cbf012f936ce", + "metadata": {}, + "source": [ + "Now here's my plan:\n", + "- I'll define `biggest_rectangle` to find the rectangle with the largest area wholy inside the red tiles.\n", + "- It will do that by using `split_tiles` to split the tiles into two halves and find the (blue above) corner points.\n", + "- I'll define `biggest_rectangle_from_corner` and call it twice; one with the top half of the tiles and top corner; once with the corresponding bottom.\n", + "- The function `any_intrusions` checks to see if a red tile is completely inside the rectangle defined by the corners. It is ok for a red tile to be on the border; but if it is inside, then the rectangle is not all red or green." + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "id": "c7dc467a-7f9c-4622-8f39-6e97dfa8d96b", + "metadata": {}, + "outputs": [], + "source": [ + "def biggest_rectangle(red_tiles: List[Point]) -> Tuple[float, Corners]:\n", + " \"\"\"Find the biggest rectangle that stays within the interior and border of the red tiles,\n", + " and return a tuple of its area and its corners.\"\"\"\n", + " top_tiles, bot_tiles, (top_corner, bot_corner) = split_tiles(red_tiles)\n", + " return max(biggest_rectangle_from_corner(top_tiles, top_corner),\n", + " biggest_rectangle_from_corner(bot_tiles, bot_corner))\n", + "\n", + "def biggest_rectangle_from_corner(tiles: List[Point], corner1: Point) -> Tuple[float, Corners]:\n", + " \"\"\"Find the biggest rectangle that stays within the interior and border of the tiles,\n", + " and return a tuple of its area and its corners.\"\"\"\n", + " for corner2 in reversed(sorted(tiles, key=lambda p: tile_area((p, corner1)))):\n", + " corners = (corner1, corner2)\n", + " if not any_intrusions(tiles, corners):\n", + " return tile_area(corners), corners\n", + "\n", + "def any_intrusions(tiles: List[Point], corners: Corners) -> bool:\n", + " \"\"\"Does any point p in tiles intrude inside the rectangle defined by the corners?\"\"\"\n", + " # This doesn't handle all possibilities, but it does handle what I see in my input\n", + " xrange = range(min(Xs(corners)) + 1, max(Xs(corners)))\n", + " yrange = range(min(Ys(corners)) + 1, max(Ys(corners)))\n", + " return any(X_(p) in xrange and Y_(p) in yrange\n", + " for p in tiles)" + ] + }, + { + "cell_type": "markdown", + "id": "9668f822-7e37-46fb-a642-eeee8376cb37", + "metadata": {}, + "source": [ + "I get the following answer, which Advent of Code verified as correct." + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "7f3350dd-0686-445c-990d-263bba4ba708", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Puzzle 9.2: .0083 seconds, answer 1529675217 correct" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "answer(9.2, 1529675217, lambda:\n", + " biggest_rectangle(red_tiles)[0])" + ] + }, + { + "cell_type": "markdown", + "id": "771fad50-cfa1-4f26-b0a4-80bc47887330", + "metadata": {}, + "source": [ + "I'll plot the result in a larger figure size to make it easier to see the largest rectangle (in blue):" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "id": "80433df6-4c37-4ed8-86cb-234fb0f9c812", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABI8AAAMtCAYAAAAWhlFpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAACkFUlEQVR4nOz9f3hc9X3n/b80Y1vYMlacENsrHXDpLY09lDRJjUPAxZYdwC0YwpWlJBj8la9MsLYoJq6hSUn3uppkUyiEhezama7FzhUEIbeb+2Zp04RQuIuqYhIH1403OAJhdjH4CByzjSNHwkhGc75/fBidmdGZmTOj+T3Px3Wda86c+czMsS2PZt7zeb8+TY7jOAIAAAAAAAA8BCp9AgAAAAAAAKheFI8AAAAAAACQEcUjAAAAAAAAZETxCAAAAAAAABlRPAIAAAAAAEBGFI8AAAAAAACQEcUjAAAAAAAAZDSn0idQ7eLxuN544w2dffbZampqqvTpAAAAAAAAFIXjOPrNb36jtrY2BQKZ5xdRPMrhjTfe0Lnnnlvp0wAAAAAAACiJY8eOybKsjLdTPMrh7LPPlmT+IhctWlThswEAAAAAACiOU6dO6dxzz52ufWRC8SiHRKvaokWLKB4BAAAAAIC6kyumh8BsAAAAAAAAZETxCAAAAAAAABlRPAIAAAAAAEBGFI8AAAAAAACQEcUjAAAAAAAAZETxCAAAAAAAABlRPAIAAAAAAEBGFI8AAAAAAACQEcUjAAAAAAAAZETxCAAAAAAAABlRPAIAAAAAAEBGFI8AAAAAAACQEcUjAAAAAAAAZETxCAAAAAAAABlRPAIAAAAAAEBGFI8AAAAAAACQEcUjAAAAAAAAZJR38eif//mfdc0116itrU1NTU3627/925TbHcfRV77yFbW1tWn+/Pnq6urSL37xi5QxExMT2r59u8455xy1tLTo2muvlW3bKWNOnjypLVu2qLW1Va2trdqyZYt+/etfp4x5/fXXdc0116ilpUXnnHOObrvtNk1OTqaMeeGFF7Ru3TrNnz9f7e3t+trXvibHcfL9YwMAAAAAADSkvItH4+Pj+vCHP6zdu3d73n7vvffq/vvv1+7du3XgwAEtW7ZMV1xxhX7zm99Mj9mxY4cef/xx7d27V/v27dPY2Jg2bdqkqamp6TGbN2/WoUOH9OSTT+rJJ5/UoUOHtGXLlunbp6amdPXVV2t8fFz79u3T3r179dhjj+n222+fHnPq1CldccUVamtr04EDB7Rr1y7dd999uv/++/P9YwMAAAAAADSkJmcW03Campr0+OOP67rrrpNkZh21tbVpx44d+tKXviTJzDJaunSp7rnnHvX09Gh0dFQf/OAH9cgjj+jTn/60JOmNN97QueeeqyeeeEIbN27Uiy++qAsuuED79+/XxRdfLEnav3+/LrnkEr300ktasWKFfvSjH2nTpk06duyY2traJEl79+7V1q1bdeLECS1atEh//dd/rTvvvFO//OUv1dzcLEn6q7/6K+3atUu2baupqSnnn/HUqVNqbW3V6OioFi1aVOhfFQAAAAAAQFXxW/MoaubRq6++quPHj+vKK6+cPtbc3Kx169bpxz/+sSTp4MGDOnPmTMqYtrY2XXjhhdNjfvKTn6i1tXW6cCRJH//4x9Xa2poy5sILL5wuHEnSxo0bNTExoYMHD06PWbdu3XThKDHmjTfe0NGjRz3/DBMTEzp16lTKBgAAAAAA0KiKWjw6fvy4JGnp0qUpx5cuXTp92/HjxzVv3jwtXrw465glS5bMePwlS5akjEl/nsWLF2vevHlZxySuJ8aku/vuu6dzllpbW3Xuuefm/oMDAAAAAADUqZKstpbeDuY4Ts4WsfQxXuOLMSbRpZfpfO68806Njo5Ob8eOHct63gAAAAAAAPWsqMWjZcuWSZo5q+fEiRPTM36WLVumyclJnTx5MuuYX/7ylzMe/6233koZk/48J0+e1JkzZ7KOOXHihKSZs6MSmpubtWjRopQNAAAAAACgURW1eHT++edr2bJlevrpp6ePTU5OanBwUJdeeqkkadWqVZo7d27KmDfffFOHDx+eHnPJJZdodHRUzz///PSYn/70pxodHU0Zc/jwYb355pvTY5566ik1Nzdr1apV02P++Z//WZOTkylj2tra9Fu/9VvF/KMDAAAAAADUpbyLR2NjYzp06JAOHTokyYRkHzp0SK+//rqampq0Y8cO3XXXXXr88cd1+PBhbd26VQsWLNDmzZslSa2trYpEIrr99tv1j//4j/rZz36mm2++WR/60Id0+eWXS5LC4bD+4A/+QLfccov279+v/fv365ZbbtGmTZu0YsUKSdKVV16pCy64QFu2bNHPfvYz/eM//qPuuOMO3XLLLdOzhTZv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8JIpAoPsIhSZ35oHM4+AUunvd/fDYbMaQvKKCbFY5c4NAAAAQG1IjsCwLJNxROEIZUbxCCgF25a2b3evx+PSo4+6PcrxuFm5zbYrc34AAAAAqodtm/Brr88HIyPlPx8gDcUjoBSOHMm9tObUlJlyCgAAAKBxxWKpHQrRqMk3SgiH6VpAxZF5lAOZRyiIbZsX/mwFpGBQOnqUKacAAABAo/LzuUHiswNKhswjoJIsa+ZqCDfd5N7O6ggAAAAA/HQsSHQtoOKYeZQDM48wK8mrISxe7L1iAgAAAIDG5DXzKPDeHI/kY8w8Qokw8wioBvmuhpAtKA8AAABAfbEsadcu93owaDoY0rsY6FpAhRW9eHT33Xdr9erVOvvss7VkyRJdd911Gh4eThnjOI6+8pWvqK2tTfPnz1dXV5d+8YtfpIyZmJjQ9u3bdc4556ilpUXXXnut7LQP1CdPntSWLVvU2tqq1tZWbdmyRb/+9a9Txrz++uu65ppr1NLSonPOOUe33XabJicni/3HBnLr73f3w2EThDc+7m7RaGpQHqF4AAAAQP3r7nb3h4akSMRsR4+aL5aPHjXXgQoqevFocHBQvb292r9/v55++mm9++67uvLKKzU+Pj495t5779X999+v3bt368CBA1q2bJmuuOIK/eY3v5kes2PHDj3++OPau3ev9u3bp7GxMW3atElTU1PTYzZv3qxDhw7pySef1JNPPqlDhw5py5Yt07dPTU3p6quv1vj4uPbt26e9e/fqscce0+23317sPzaQnW1L27e71+NxqbfXtLEltt5ed2pqPC719DADCQAAAGgk7e3ufr5dDEAJlTzz6K233tKSJUs0ODiotWvXynEctbW1aceOHfrSl74kycwyWrp0qe655x719PRodHRUH/zgB/XII4/o05/+tCTpjTfe0LnnnqsnnnhCGzdu1IsvvqgLLrhA+/fv18UXXyxJ2r9/vy655BK99NJLWrFihX70ox9p06ZNOnbsmNra2iRJe/fu1datW3XixAnPfr6JiQlNTExMXz916pTOPfdcMo8wOwMDZkZRIffr6ir66QAAAAAoM9s2AdmdnakFofFxslFRMVWTeTQ6OipJev/73y9JevXVV3X8+HFdeeWV02Oam5u1bt06/fjHP5YkHTx4UGfOnEkZ09bWpgsvvHB6zE9+8hO1trZOF44k6eMf/7haW1tTxlx44YXThSNJ2rhxoyYmJnTw4EHP87377run2+BaW1t17rnnFuOvAY2us9MNvksIBs0vh7Exc+l1e0dH+c4RAAAAQGnEYqkRFckRFn197rhwmPgKVKWSFo8cx9HOnTv1+7//+7rwwgslScePH5ckLV26NGXs0qVLp287fvy45s2bp8WLF2cds2TJkhnPuWTJkpQx6c+zePFizZs3b3pMujvvvFOjo6PT27Fjx/L9YwMzWZZ36F0oJLW0mMv0oDxC8QAAAIDaZ9vStm2pERXJERY7d7pjia9AlZpTygf//Oc/r5///Ofat2/fjNuamppSrjuOM+NYuvQxXuMLGZOsublZzc3NWc8DKEgkIm3cKL3yiplRlF4Y6u42v0QkE5THdFUAAACg9h054haO/JiaMp8Z+CIZVaRkM4+2b9+u73//+xoYGJCV9EO/bNkySZox8+fEiRPTs4SWLVumyclJnTx5MuuYX/7ylzOe96233koZk/48J0+e1JkzZ2bMSALKwm/oXXJQHgAAAIDalS3CgvgK1IiiF48cx9HnP/95/Y//8T/0zDPP6Pzzz0+5/fzzz9eyZcv09NNPTx+bnJzU4OCgLr30UknSqlWrNHfu3JQxb775pg4fPjw95pJLLtHo6Kief/756TE//elPNTo6mjLm8OHDevPNN6fHPPXUU2pubtaqVauK/UcHimdkxN23bROczdRVAAAAoPZYlndERShkNq94C2YdocoUfbW1W2+9Vd/97nf1d3/3d1qxYsX08dbWVs2fP1+SdM899+juu+/Wt7/9bXV2duquu+7SP/3TP2l4eFhnn322JOmP//iP9YMf/EAPPfSQ3v/+9+uOO+7Qv/3bv+ngwYMKvvcf6w//8A/1xhtvaM+ePZKkbdu2afny5fr7v/97SdLU1JQ+8pGPaOnSpfrGN76hX/3qV9q6dauuu+467Ur+z5uF3+RxYNaiUbdtLRBwf8Fs326muQYC5hdLJFK5cwQAAACQv1wrqtl25ngLoIT81jyKXjzKlCX07W9/W1u3bpVkZid99atf1Z49e3Ty5EldfPHF+ta3vjUdqi1J77zzjv70T/9U3/3ud3X69Gl94hOfUDQaTVn97Fe/+pVuu+02ff/735ckXXvttdq9e7fe9773TY95/fXXdeutt+qZZ57R/PnztXnzZt13332+c40oHqEs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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "_, corners = biggest_rectangle(red_tiles)\n", + "((x1, y1), (x2, y2)) = corners\n", + "\n", + "plt.figure(figsize=(14, 10))\n", + "plt.plot(*T(red_tiles), 'r.-')\n", + "plt.plot([x1, x1, x2, x2, x1], [y1, y2, y2, y1, y1], 'b:');" + ] + }, + { + "cell_type": "markdown", + "id": "b4e35203-687a-434e-88f5-0afea9f31c57", + "metadata": {}, + "source": [ + "Two remarks to be made here. One, this was the first puzzle of the year that was **difficult**. Two, my solution is **unsatisfying** in that it works for my input, and I strongly suspect that it would work for every other person's input, because Eric Wastl probably creating them all to be similar. But it does not work on every possible input allowed by the rules. To cover every possible input I would need to try every red tile as a possibility for the first corner, rather than trying just two possibilities. And the `any_intrusions` function would have to be more complex (see [ChatGPT's solution to 9.2](Advent-2025-AI.ipynb) for example). So my code solves my puzzle, I'm pretty sure it would solve your puzzle, but it doesn't solve all possible puzzles." + ] + }, { "cell_type": "markdown", "id": "7f31ae9b-6606-40b0-9bb1-ed9b3fe3cbf0", @@ -1704,7 +2008,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 66, "id": "ba36579c-d0b4-4fd3-939c-0026ecddd7e9", "metadata": {}, "outputs": [ @@ -1712,24 +2016,26 @@ "name": "stdout", "output_type": "stream", "text": [ - "Puzzle 1.1: .0006 seconds, answer 1182 correct\n", - "Puzzle 1.2: .0009 seconds, answer 6907 correct\n", - "Puzzle 2.1: .0032 seconds, answer 23560874270 correct\n", - "Puzzle 2.2: .0037 seconds, answer 44143124633 correct\n", + "Puzzle 1.1: .0007 seconds, answer 1182 correct\n", + "Puzzle 1.2: .0010 seconds, answer 6907 correct\n", + "Puzzle 2.1: .0029 seconds, answer 23560874270 correct\n", + "Puzzle 2.2: .0043 seconds, answer 44143124633 correct\n", "Puzzle 3.1: .0006 seconds, answer 17085 correct\n", "Puzzle 3.2: .0020 seconds, answer 169408143086082 correct\n", - "Puzzle 4.1: .0527 seconds, answer 1569 correct\n", - "Puzzle 4.2: .1424 seconds, answer 9280 correct\n", - "Puzzle 5.1: .0079 seconds, answer 635 correct\n", + "Puzzle 4.1: .0511 seconds, answer 1569 correct\n", + "Puzzle 4.2: .1380 seconds, answer 9280 correct\n", + "Puzzle 5.1: .0072 seconds, answer 635 correct\n", "Puzzle 5.2: .0001 seconds, answer 369761800782619 correct\n", "Puzzle 6.1: .0015 seconds, answer 5877594983578 correct\n", - "Puzzle 6.2: .0039 seconds, answer 11159825706149 correct\n", + "Puzzle 6.2: .0038 seconds, answer 11159825706149 correct\n", "Puzzle 7.1: .0008 seconds, answer 1681 correct\n", - "Puzzle 7.2: .0014 seconds, answer 422102272495018 correct\n", - "Puzzle 8.1: .6207 seconds, answer 24360 correct\n", - "Puzzle 8.2: .6530 seconds, answer 2185817796 correct\n", + "Puzzle 7.2: .0015 seconds, answer 422102272495018 correct\n", + "Puzzle 8.1: .5863 seconds, answer 24360 correct\n", + "Puzzle 8.2: .6265 seconds, answer 2185817796 correct\n", + "Puzzle 9.1: .0285 seconds, answer 4772103936 correct\n", + "Puzzle 9.2: .0083 seconds, answer 1529675217 correct\n", "\n", - "Time in seconds: sum = 1.495, mean = .093, median = .003, max = .653\n" + "Time in seconds: sum = 1.465, mean = .081, median = .003, max = .626\n" ] } ],