From 7bf07c03eaea5ca0fd731c9ff2cdeb624cf4a4e8 Mon Sep 17 00:00:00 2001 From: Peter Norvig Date: Tue, 17 Dec 2024 23:32:51 -0800 Subject: [PATCH] Add files via upload --- ipynb/Advent-2024.ipynb | 229 ++++++++++++++++++++-------------------- 1 file changed, 114 insertions(+), 115 deletions(-) diff --git a/ipynb/Advent-2024.ipynb b/ipynb/Advent-2024.ipynb index 916310b..9b5f41e 100644 --- a/ipynb/Advent-2024.ipynb +++ b/ipynb/Advent-2024.ipynb @@ -136,7 +136,7 @@ { "data": { "text/plain": [ - "Puzzle 1.1: .0002 seconds, answer 1830467 ok" + "Puzzle 1.1: .0001 seconds, answer 1830467 ok" ] }, "execution_count": 8, @@ -334,7 +334,7 @@ { "data": { "text/plain": [ - "Puzzle 2.2: .0023 seconds, answer 328 ok" + "Puzzle 2.2: .0022 seconds, answer 328 ok" ] }, "execution_count": 19, @@ -463,7 +463,7 @@ { "data": { "text/plain": [ - "Puzzle 3.2: .0005 seconds, answer 75920122 ok" + "Puzzle 3.2: .0004 seconds, answer 75920122 ok" ] }, "execution_count": 27, @@ -553,7 +553,7 @@ { "data": { "text/plain": [ - "Puzzle 4.1: .0328 seconds, answer 2401 ok" + "Puzzle 4.1: .0339 seconds, answer 2401 ok" ] }, "execution_count": 32, @@ -608,7 +608,7 @@ { "data": { "text/plain": [ - "Puzzle 4.2: .0268 seconds, answer 1822 ok" + "Puzzle 4.2: .0267 seconds, answer 1822 ok" ] }, "execution_count": 35, @@ -823,7 +823,7 @@ { "data": { "text/plain": [ - "Puzzle 5.2: .0008 seconds, answer 4130 ok" + "Puzzle 5.2: .0009 seconds, answer 4130 ok" ] }, "execution_count": 46, @@ -923,7 +923,7 @@ { "data": { "text/plain": [ - "Puzzle 6.1: .0014 seconds, answer 5329 ok" + "Puzzle 6.1: .0016 seconds, answer 5329 ok" ] }, "execution_count": 52, @@ -993,7 +993,7 @@ { "data": { "text/plain": [ - "Puzzle 6.2: 1.9643 seconds, answer 2162 ok" + "Puzzle 6.2: 1.9577 seconds, answer 2162 ok" ] }, "execution_count": 55, @@ -1126,7 +1126,7 @@ " target, first, *rest = numbers\n", " results = {first} # A set of all possible results of the partial computation\n", " for y in rest:\n", - " results = {op(x, y) for x in results if x <= target for op in operators}\n", + " results = [op(x, y) for x in results if x <= target for op in operators]\n", " return target in results" ] }, @@ -1139,7 +1139,7 @@ { "data": { "text/plain": [ - "Puzzle 7.1: .0213 seconds, answer 1985268524462 ok" + "Puzzle 7.1: .0139 seconds, answer 1985268524462 ok" ] }, "execution_count": 64, @@ -1171,7 +1171,7 @@ { "data": { "text/plain": [ - "Puzzle 7.2: 1.0804 seconds, answer 150077710195188 ok" + "Puzzle 7.2: .7986 seconds, answer 150077710195188 ok" ] }, "execution_count": 66, @@ -1267,7 +1267,7 @@ { "data": { "text/plain": [ - "Puzzle 8.1: .0029 seconds, answer 220 ok" + "Puzzle 8.1: .0028 seconds, answer 220 ok" ] }, "execution_count": 71, @@ -1344,7 +1344,7 @@ { "data": { "text/plain": [ - "Puzzle 8.2: .0030 seconds, answer 813 ok" + "Puzzle 8.2: .0033 seconds, answer 813 ok" ] }, "execution_count": 75, @@ -1457,7 +1457,7 @@ { "data": { "text/plain": [ - "Puzzle 9.1: .0197 seconds, answer 6332189866718 ok" + "Puzzle 9.1: .0201 seconds, answer 6332189866718 ok" ] }, "execution_count": 81, @@ -1537,7 +1537,7 @@ { "data": { "text/plain": [ - "Puzzle 9.2: 2.7519 seconds, answer 6353648390778 ok" + "Puzzle 9.2: 2.7191 seconds, answer 6353648390778 ok" ] }, "execution_count": 84, @@ -1646,7 +1646,7 @@ { "data": { "text/plain": [ - "Puzzle 10.1: .0045 seconds, answer 744 ok" + "Puzzle 10.1: .0050 seconds, answer 744 ok" ] }, "execution_count": 90, @@ -1839,7 +1839,7 @@ { "data": { "text/plain": [ - "Puzzle 11.1: .0671 seconds, answer 194482 ok" + "Puzzle 11.1: .0681 seconds, answer 194482 ok" ] }, "execution_count": 100, @@ -1922,7 +1922,7 @@ { "data": { "text/plain": [ - "Puzzle 11.2: .0599 seconds, answer 232454623677743 ok" + "Puzzle 11.2: .0595 seconds, answer 232454623677743 ok" ] }, "execution_count": 105, @@ -2054,7 +2054,7 @@ { "data": { "text/plain": [ - "Puzzle 12.1: .0329 seconds, answer 1402544 ok" + "Puzzle 12.1: .0331 seconds, answer 1402544 ok" ] }, "execution_count": 113, @@ -2127,7 +2127,7 @@ { "data": { "text/plain": [ - "Puzzle 12.1: .0307 seconds, answer 1402544 ok" + "Puzzle 12.1: .0308 seconds, answer 1402544 ok" ] }, "execution_count": 116, @@ -2149,7 +2149,7 @@ { "data": { "text/plain": [ - "Puzzle 12.2: .0430 seconds, answer 862486 ok" + "Puzzle 12.2: .0423 seconds, answer 862486 ok" ] }, "execution_count": 117, @@ -2269,7 +2269,7 @@ { "data": { "text/plain": [ - "Puzzle 13.1: .0102 seconds, answer 29598 ok" + "Puzzle 13.1: .0107 seconds, answer 29598 ok" ] }, "execution_count": 122, @@ -2781,42 +2781,42 @@ "\n", "\n", "
\n", - " \n", + " \n", "
\n", - " \n", + " oninput=\"anime68603ecbe714d0aacd3edf31873c115.set_frame(parseInt(this.value));\">\n", "
\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", "
\n", - "
\n", - " \n", - " \n", - " Once\n", + " \n", - " \n", - " Loop\n", + " \n", - " \n", + " \n", "
\n", "
\n", "
\n", @@ -2826,9 +2826,9 @@ " /* Instantiate the Animation class. */\n", " /* The IDs given should match those used in the template above. */\n", " (function() {\n", - " var img_id = \"_anim_img1e0a1734c1b64f26ba0a7f3051a934a3\";\n", - " var slider_id = \"_anim_slider1e0a1734c1b64f26ba0a7f3051a934a3\";\n", - " var loop_select_id = \"_anim_loop_select1e0a1734c1b64f26ba0a7f3051a934a3\";\n", + " var img_id = \"_anim_imge68603ecbe714d0aacd3edf31873c115\";\n", + " var slider_id = \"_anim_slidere68603ecbe714d0aacd3edf31873c115\";\n", + " var loop_select_id = \"_anim_loop_selecte68603ecbe714d0aacd3edf31873c115\";\n", " var frames = new Array(3);\n", " \n", " frames[0] = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA8AAAALQCAYAAABfdxm0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90\\\n", @@ -5600,14 +5600,14 @@ " /* set a timeout to make sure all the above elements are created before\n", " the object is initialized. */\n", " setTimeout(function() {\n", - " anim1e0a1734c1b64f26ba0a7f3051a934a3 = new Animation(frames, img_id, slider_id, 200.0,\n", + " anime68603ecbe714d0aacd3edf31873c115 = new Animation(frames, img_id, slider_id, 200.0,\n", " loop_select_id);\n", " }, 0);\n", " })()\n", "\n" ], "text/plain": [ - "" + "" ] }, "execution_count": 140, @@ -5840,42 +5840,42 @@ "\n", "\n", "
\n", - " \n", + " \n", "
\n", - " \n", + " oninput=\"anim9a2476b9e7bf4f5e9a2e2f3b191f3f0b.set_frame(parseInt(this.value));\">\n", "
\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", "
\n", - "
\n", - " \n", - " \n", - " Once\n", + " \n", - " \n", - " Loop\n", + " \n", - " \n", + " \n", "
\n", "
\n", "
\n", @@ -5885,9 +5885,9 @@ " /* Instantiate the Animation class. */\n", " /* The IDs given should match those used in the template above. */\n", " (function() {\n", - " var img_id = \"_anim_img4e5b0d0e6fe24e0ea5f0bb1cec42557f\";\n", - " var slider_id = \"_anim_slider4e5b0d0e6fe24e0ea5f0bb1cec42557f\";\n", - " var loop_select_id = \"_anim_loop_select4e5b0d0e6fe24e0ea5f0bb1cec42557f\";\n", + " var img_id = \"_anim_img9a2476b9e7bf4f5e9a2e2f3b191f3f0b\";\n", + " var slider_id = \"_anim_slider9a2476b9e7bf4f5e9a2e2f3b191f3f0b\";\n", + " var loop_select_id = \"_anim_loop_select9a2476b9e7bf4f5e9a2e2f3b191f3f0b\";\n", " var frames = new Array(1);\n", " \n", " frames[0] = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA8AAAALQCAYAAABfdxm0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90\\\n", @@ -6565,14 +6565,14 @@ " /* set a timeout to make sure all the above elements are created before\n", " the object is initialized. */\n", " setTimeout(function() {\n", - " anim4e5b0d0e6fe24e0ea5f0bb1cec42557f = new Animation(frames, img_id, slider_id, 200.0,\n", + " anim9a2476b9e7bf4f5e9a2e2f3b191f3f0b = new Animation(frames, img_id, slider_id, 200.0,\n", " loop_select_id);\n", " }, 0);\n", " })()\n", "\n" ], "text/plain": [ - "" + "" ] }, "execution_count": 143, @@ -6604,7 +6604,7 @@ { "data": { "text/plain": [ - "Puzzle 14.2: 1.8645 seconds, answer 6876 ok" + "Puzzle 14.2: 1.8663 seconds, answer 6876 ok" ] }, "execution_count": 145, @@ -6723,7 +6723,7 @@ { "data": { "text/plain": [ - "Puzzle 15.1: .0248 seconds, answer 1563092 ok" + "Puzzle 15.1: .0241 seconds, answer 1563092 ok" ] }, "execution_count": 150, @@ -6800,7 +6800,7 @@ { "data": { "text/plain": [ - "Puzzle 15.1: .0299 seconds, answer 1563092 ok" + "Puzzle 15.1: .0290 seconds, answer 1563092 ok" ] }, "execution_count": 153, @@ -6822,7 +6822,7 @@ { "data": { "text/plain": [ - "Puzzle 15.2: .0415 seconds, answer 1582688 ok" + "Puzzle 15.2: .0419 seconds, answer 1582688 ok" ] }, "execution_count": 154, @@ -6979,7 +6979,7 @@ { "data": { "text/plain": [ - "Puzzle 16.1: .1473 seconds, answer 103512 ok" + "Puzzle 16.1: .1470 seconds, answer 103512 ok" ] }, "execution_count": 162, @@ -7043,7 +7043,7 @@ { "data": { "text/plain": [ - "Puzzle 16.2: .8496 seconds, answer 554 ok" + "Puzzle 16.2: .8517 seconds, answer 554 ok" ] }, "execution_count": 165, @@ -7128,7 +7128,7 @@ "source": [ "### Part 1: What do you get if you use commas to join the output values?\n", "\n", - "Now we have to run the program. The computer has eight opcodes; each opcode operates on the following value in memory; some instructions take the operand literally, and some compute a **combo** value from it (equal to register A, B, or C if the value is 4, 5, or 6, respectively; otherwise the value itself). There is a program counter (pc) that increments by 2, unless there is a branch instuction (opcode 3). See the [day's description](https://adventofcode.com/2024/day/17)) for details on how the opcodes work. Or look at my `run_program` function, which yields the outputs from running the program:" + "Now we have to run the program. The computer has eight opcodes; each opcode operates on the following value in memory; some instructions take the operand literally, and some compute a **combo** value from it (equal to register A, B, or C if the value is 4, 5, or 6, respectively; otherwise the value itself). There is a program counter (pc) that increments by 2, unless there is a branch instuction (opcode 3). See the [day's description](https://adventofcode.com/2024/day/17) for details on how the opcodes work. Or look at my `run_program` function, which yields the outputs from running the program:" ] }, { @@ -7138,7 +7138,7 @@ "metadata": {}, "outputs": [], "source": [ - "def run_program(computer):\n", + "def run_program(computer) -> Iterable[int]:\n", " \"\"\"Run the program on the computer, yielding each output.\"\"\"\n", " A, B, C, prog = computer\n", " pc = 0\n", @@ -7322,11 +7322,11 @@ "metadata": {}, "source": [ "That is, my program ends in `5,3,0`, and an octal `7` outputs a `0`; an octal `0o72` outputs `3,0`, and octal `0o726` outputs `5,3,0`. So here's my approach for finding the Quine program:\n", - "- I'm going to keerp a set of candidate values for `A` as the set `As`.\n", + "- I'm going to keep a set of candidate values for `A` as the set `As`.\n", "- The set starts with just `{0}`.\n", "- On each iteration I try appending each octal digit to each element of the set `As`.\n", "- I keep the candidate `A` values whose output matches the tail of the program's output.\n", - "- Iterate this for each digit and return the set of `A` vcalues that produce the whole program.\n", + "- Iterate this for each digit and return the set of `A` values that produce the whole program.\n", "- Take the minium of the set." ] }, @@ -7339,7 +7339,7 @@ { "data": { "text/plain": [ - "Puzzle 17.2: .0232 seconds, answer 267265166222235 ok" + "Puzzle 17.2: .0039 seconds, answer 267265166222235 ok" ] }, "execution_count": 179, @@ -7421,7 +7421,7 @@ "\n", "When a byte falls it creates a barrier. Our task is to find a path that avoids the barriers, from the start in the upper left to the exit in the lower right of a 71 x 71 grid that is the memory board. \n", "\n", - "This is another search problem, like the maze in Day 16, but without the complications; this time we can take a step in any of the four cardinal directions at unit cost. The problem description says that we should first consider just the first kilobyte (1024 bytes), and I was worried that if I just hand those points to my `Grid` class, it wouldn't cover the whole 71 x 71 grid. Therefore, I created a grid with empty spaces, and then updated with the falling bytes. The function `memory_path` returns a path, and we can then ask for its length to get the answer." + "This is another search problem, like the maze in Day 16, but without the complications (e.g. costs for turning right or left). The problem description for today says that we should first consider just the first kilobyte (1024 falling bytes), and I was worried that if I just hand those points to my `Grid` class, it wouldn't cover the whole 71 x 71 grid. Therefore, I created a grid with empty spaces, and then updated with the falling bytes. The function `memory_path` returns a path, and we can then ask for its length to get the answer." ] }, { @@ -7448,7 +7448,7 @@ { "data": { "text/plain": [ - "Puzzle 18.1: .0138 seconds, answer 344 ok" + "Puzzle 18.1: .0141 seconds, answer 344 ok" ] }, "execution_count": 184, @@ -7468,9 +7468,9 @@ "source": [ "### Part 2: What are the coordinates of the first byte that will prevent the exit from being reachable from your starting position?\n", "\n", - "After 1024 bytes fall there is a path from start to exit, but as more bytes fall we might have to switch to a different path, and eventually there may be no path. We're asked for the first byte position that blocks the last remaining path. I can think of three ways to handle this:\n", + "After 1024 bytes fall there is a path from start to exit, but as more bytes fall we might have to switch to a different path, and eventually there will be no path. We're asked for the `x,y` position of the first falling byte that blocks off all paths. I can think of three ways to handle this:\n", "1) Add falling bytes one at a time and repeat the A-star search each time. **Slow!**\n", - "2) Add falling bytes in binary search fashion: We know adding no bytes is good for getting a path and adding all of them is bad; try half way and then update good or bad depending on whether we found a path. **Pretty fast.**\n", + "2) Add falling bytes in binary search fashion: We know adding no bytes is **good** for getting a path and adding all of them is **bad**; try half way and then update **good** or **bad** depending on whether we found a path. **Fast!**\n", "3) Optimize (2) by checking which of the falling bytes intersects with the current path; if *n* bytes are ok, and byte *n*+1 is not on the path for *n*, then *n*+1 is ok. Might be a bit faster, but in my opinion not worth the code complexity. We could also incrementally add and remove " ] }, @@ -7487,8 +7487,7 @@ " bad = len(falling_bytes) - 1\n", " while bad - good > 1:\n", " mid = (good + bad) // 2\n", - " path = memory_path(falling_bytes[:mid + 1])\n", - " if path == search_failure:\n", + " if memory_path(falling_bytes[:mid + 1]) == search_failure:\n", " bad = mid\n", " else:\n", " good = mid\n", @@ -7504,7 +7503,7 @@ { "data": { "text/plain": [ - "Puzzle 18.2: .0348 seconds, answer 46,18 ok" + "Puzzle 18.2: .0359 seconds, answer 46,18 ok" ] }, "execution_count": 187, @@ -7532,7 +7531,7 @@ "source": [ "# Summary\n", "\n", - "So far, I've solved all the puzzles. Most of them run in well under a second (the median is less than a hundreth of a second), but four of them take over a second." + "So far, I've solved all the puzzles. Most run in well under a second (the median is less than a hundreth of a second), but three take over a second." ] }, { @@ -7545,46 +7544,46 @@ "name": "stdout", "output_type": "stream", "text": [ - "Puzzle 1.1: .0002 seconds, answer 1830467 ok\n", + "Puzzle 1.1: .0001 seconds, answer 1830467 ok\n", "Puzzle 1.2: .0001 seconds, answer 26674158 ok\n", "Puzzle 2.1: .0004 seconds, answer 257 ok\n", - "Puzzle 2.2: .0023 seconds, answer 328 ok\n", + "Puzzle 2.2: .0022 seconds, answer 328 ok\n", "Puzzle 3.1: .0006 seconds, answer 156388521 ok\n", - "Puzzle 3.2: .0005 seconds, answer 75920122 ok\n", - "Puzzle 4.1: .0328 seconds, answer 2401 ok\n", - "Puzzle 4.2: .0268 seconds, answer 1822 ok\n", + "Puzzle 3.2: .0004 seconds, answer 75920122 ok\n", + "Puzzle 4.1: .0339 seconds, answer 2401 ok\n", + "Puzzle 4.2: .0267 seconds, answer 1822 ok\n", "Puzzle 5.1: .0007 seconds, answer 5762 ok\n", - "Puzzle 5.2: .0008 seconds, answer 4130 ok\n", - "Puzzle 6.1: .0014 seconds, answer 5329 ok\n", - "Puzzle 6.2: 1.9643 seconds, answer 2162 ok\n", - "Puzzle 7.1: .0213 seconds, answer 1985268524462 ok\n", - "Puzzle 7.2: 1.0804 seconds, answer 150077710195188 ok\n", + "Puzzle 5.2: .0009 seconds, answer 4130 ok\n", + "Puzzle 6.1: .0016 seconds, answer 5329 ok\n", + "Puzzle 6.2: 1.9577 seconds, answer 2162 ok\n", + "Puzzle 7.1: .0139 seconds, answer 1985268524462 ok\n", + "Puzzle 7.2: .7986 seconds, answer 150077710195188 ok\n", "Puzzle 8.1: .0026 seconds, answer 220 ok\n", - "Puzzle 8.2: .0030 seconds, answer 813 ok\n", - "Puzzle 9.1: .0197 seconds, answer 6332189866718 ok\n", - "Puzzle 9.2: 2.7519 seconds, answer 6353648390778 ok\n", - "Puzzle 10.1: .0045 seconds, answer 744 ok\n", + "Puzzle 8.2: .0033 seconds, answer 813 ok\n", + "Puzzle 9.1: .0201 seconds, answer 6332189866718 ok\n", + "Puzzle 9.2: 2.7191 seconds, answer 6353648390778 ok\n", + "Puzzle 10.1: .0050 seconds, answer 744 ok\n", "Puzzle 10.2: .0062 seconds, answer 1651 ok\n", "Puzzle 11.1: .0015 seconds, answer 194482 ok\n", - "Puzzle 11.2: .0599 seconds, answer 232454623677743 ok\n", - "Puzzle 12.1: .0307 seconds, answer 1402544 ok\n", - "Puzzle 12.2: .0430 seconds, answer 862486 ok\n", + "Puzzle 11.2: .0595 seconds, answer 232454623677743 ok\n", + "Puzzle 12.1: .0308 seconds, answer 1402544 ok\n", + "Puzzle 12.2: .0423 seconds, answer 862486 ok\n", "Puzzle 13.1: .0002 seconds, answer 29598 ok\n", "Puzzle 13.2: .0004 seconds, answer 93217456941970 ok\n", "Puzzle 14.1: .0001 seconds, answer 216027840 ok\n", - "Puzzle 14.2: 1.8645 seconds, answer 6876 ok\n", - "Puzzle 15.1: .0299 seconds, answer 1563092 ok\n", - "Puzzle 15.2: .0415 seconds, answer 1582688 ok\n", - "Puzzle 16.1: .1473 seconds, answer 103512 ok\n", - "Puzzle 16.2: .8496 seconds, answer 554 ok\n", + "Puzzle 14.2: 1.8663 seconds, answer 6876 ok\n", + "Puzzle 15.1: .0290 seconds, answer 1563092 ok\n", + "Puzzle 15.2: .0419 seconds, answer 1582688 ok\n", + "Puzzle 16.1: .1470 seconds, answer 103512 ok\n", + "Puzzle 16.2: .8517 seconds, answer 554 ok\n", "Puzzle 17.1: .0000 seconds, answer 2,1,0,1,7,2,5,0,3 ok\n", - "Puzzle 17.2: .0232 seconds, answer 267265166222235 ok\n", - "Puzzle 18.1: .0138 seconds, answer 344 ok\n", - "Puzzle 18.2: .0348 seconds, answer 46,18 ok\n", + "Puzzle 17.2: .0039 seconds, answer 267265166222235 ok\n", + "Puzzle 18.1: .0141 seconds, answer 344 ok\n", + "Puzzle 18.2: .0359 seconds, answer 46,18 ok\n", "\n", "Correct: 36/36\n", "\n", - "Time in seconds: 0.0100 median, 0.2517 mean, 9.0607 total.\n" + "Time in seconds: 0.0056 median, 0.2422 mean, 8.7188 total.\n" ] } ],