From baf239682b10a5be50de62f18db1bf5be7e2a763 Mon Sep 17 00:00:00 2001 From: Peter Norvig Date: Thu, 26 Dec 2024 09:36:20 -0800 Subject: [PATCH] Add files via upload --- ipynb/Advent-2024.ipynb | 498 +++++++++++++++++----------------------- 1 file changed, 215 insertions(+), 283 deletions(-) diff --git a/ipynb/Advent-2024.ipynb b/ipynb/Advent-2024.ipynb index 4d9d4c3..49d4524 100644 --- a/ipynb/Advent-2024.ipynb +++ b/ipynb/Advent-2024.ipynb @@ -592,7 +592,7 @@ { "data": { "text/plain": [ - "Puzzle 4.1: .033 seconds, answer 2401 ok" + "Puzzle 4.1: .032 seconds, answer 2401 ok" ] }, "execution_count": 35, @@ -1032,7 +1032,7 @@ { "data": { "text/plain": [ - "Puzzle 6.2: 1.967 seconds, answer 2162 ok" + "Puzzle 6.2: 1.942 seconds, answer 2162 ok" ] }, "execution_count": 58, @@ -1178,7 +1178,7 @@ { "data": { "text/plain": [ - "Puzzle 7.1: .013 seconds, answer 1985268524462 ok" + "Puzzle 7.1: .014 seconds, answer 1985268524462 ok" ] }, "execution_count": 67, @@ -1220,7 +1220,7 @@ { "data": { "text/plain": [ - "Puzzle 7.2: .811 seconds, answer 150077710195188 ok" + "Puzzle 7.2: .788 seconds, answer 150077710195188 ok" ] }, "execution_count": 70, @@ -1268,7 +1268,7 @@ { "data": { "text/plain": [ - "Puzzle 7.2: .660 seconds, answer 150077710195188 ok" + "Puzzle 7.2: .646 seconds, answer 150077710195188 ok" ] }, "execution_count": 73, @@ -1552,7 +1552,7 @@ { "data": { "text/plain": [ - "Puzzle 9.1: .019 seconds, answer 6332189866718 ok" + "Puzzle 9.1: .020 seconds, answer 6332189866718 ok" ] }, "execution_count": 88, @@ -1632,7 +1632,7 @@ { "data": { "text/plain": [ - "Puzzle 9.2: 2.754 seconds, answer 6353648390778 ok" + "Puzzle 9.2: 2.680 seconds, answer 6353648390778 ok" ] }, "execution_count": 91, @@ -1934,7 +1934,7 @@ { "data": { "text/plain": [ - "Puzzle 11.1: .068 seconds, answer 194482 ok" + "Puzzle 11.1: .067 seconds, answer 194482 ok" ] }, "execution_count": 107, @@ -2017,7 +2017,7 @@ { "data": { "text/plain": [ - "Puzzle 11.2: .061 seconds, answer 232454623677743 ok" + "Puzzle 11.2: .060 seconds, answer 232454623677743 ok" ] }, "execution_count": 112, @@ -2222,7 +2222,7 @@ { "data": { "text/plain": [ - "Puzzle 12.1: .052 seconds, answer 1402544 ok" + "Puzzle 12.1: .051 seconds, answer 1402544 ok" ] }, "execution_count": 123, @@ -2878,42 +2878,42 @@ "\n", "\n", "
\n", - " \n", + " \n", "
\n", - " \n", + " oninput=\"animf59c28f9f5894974b4791611a2c64487.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", @@ -2923,9 +2923,9 @@ " /* Instantiate the Animation class. */\n", " /* The IDs given should match those used in the template above. */\n", " (function() {\n", - " var img_id = \"_anim_img5d9cef03daf64662882705f9f9bba16b\";\n", - " var slider_id = \"_anim_slider5d9cef03daf64662882705f9f9bba16b\";\n", - " var loop_select_id = \"_anim_loop_select5d9cef03daf64662882705f9f9bba16b\";\n", + " var img_id = \"_anim_imgf59c28f9f5894974b4791611a2c64487\";\n", + " var slider_id = \"_anim_sliderf59c28f9f5894974b4791611a2c64487\";\n", + " var loop_select_id = \"_anim_loop_selectf59c28f9f5894974b4791611a2c64487\";\n", " var frames = new Array(3);\n", " \n", " frames[0] = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA8AAAALQCAYAAABfdxm0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90\\\n", @@ -5697,14 +5697,14 @@ " /* set a timeout to make sure all the above elements are created before\n", " the object is initialized. */\n", " setTimeout(function() {\n", - " anim5d9cef03daf64662882705f9f9bba16b = new Animation(frames, img_id, slider_id, 200.0,\n", + " animf59c28f9f5894974b4791611a2c64487 = new Animation(frames, img_id, slider_id, 200.0,\n", " loop_select_id);\n", " }, 0);\n", " })()\n", "\n" ], "text/plain": [ - "" + "" ] }, "execution_count": 147, @@ -5937,42 +5937,42 @@ "\n", "\n", "
\n", - " \n", + " \n", "
\n", - " \n", + " oninput=\"anim341b36c396fc4a0cb12fe324af161d71.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", @@ -5982,9 +5982,9 @@ " /* Instantiate the Animation class. */\n", " /* The IDs given should match those used in the template above. */\n", " (function() {\n", - " var img_id = \"_anim_imgc28e0e9e1b144da299de29e5ae4bfa26\";\n", - " var slider_id = \"_anim_sliderc28e0e9e1b144da299de29e5ae4bfa26\";\n", - " var loop_select_id = \"_anim_loop_selectc28e0e9e1b144da299de29e5ae4bfa26\";\n", + " var img_id = \"_anim_img341b36c396fc4a0cb12fe324af161d71\";\n", + " var slider_id = \"_anim_slider341b36c396fc4a0cb12fe324af161d71\";\n", + " var loop_select_id = \"_anim_loop_select341b36c396fc4a0cb12fe324af161d71\";\n", " var frames = new Array(1);\n", " \n", " frames[0] = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA8AAAALQCAYAAABfdxm0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90\\\n", @@ -6662,14 +6662,14 @@ " /* set a timeout to make sure all the above elements are created before\n", " the object is initialized. */\n", " setTimeout(function() {\n", - " animc28e0e9e1b144da299de29e5ae4bfa26 = new Animation(frames, img_id, slider_id, 200.0,\n", + " anim341b36c396fc4a0cb12fe324af161d71 = new Animation(frames, img_id, slider_id, 200.0,\n", " loop_select_id);\n", " }, 0);\n", " })()\n", "\n" ], "text/plain": [ - "" + "" ] }, "execution_count": 150, @@ -6701,7 +6701,7 @@ { "data": { "text/plain": [ - "Puzzle 14.2: 1.869 seconds, answer 6876 ok" + "Puzzle 14.2: 1.825 seconds, answer 6876 ok" ] }, "execution_count": 152, @@ -6897,7 +6897,7 @@ { "data": { "text/plain": [ - "Puzzle 15.1: .029 seconds, answer 1563092 ok" + "Puzzle 15.1: .028 seconds, answer 1563092 ok" ] }, "execution_count": 160, @@ -7080,7 +7080,7 @@ { "data": { "text/plain": [ - "Puzzle 16.1: .147 seconds, answer 103512 ok" + "Puzzle 16.1: .144 seconds, answer 103512 ok" ] }, "execution_count": 169, @@ -7144,7 +7144,7 @@ { "data": { "text/plain": [ - "Puzzle 16.2: .852 seconds, answer 554 ok" + "Puzzle 16.2: .846 seconds, answer 554 ok" ] }, "execution_count": 172, @@ -7450,7 +7450,7 @@ { "data": { "text/plain": [ - "Puzzle 17.2: .023 seconds, answer 267265166222235 ok" + "Puzzle 17.2: .024 seconds, answer 267265166222235 ok" ] }, "execution_count": 187, @@ -7761,7 +7761,7 @@ { "data": { "text/plain": [ - "Puzzle 19.2: .187 seconds, answer 595975512785325 ok" + "Puzzle 19.2: .184 seconds, answer 595975512785325 ok" ] }, "execution_count": 204, @@ -7957,7 +7957,7 @@ { "data": { "text/plain": [ - "Puzzle 20.2: .770 seconds, answer 982891 ok" + "Puzzle 20.2: .756 seconds, answer 982891 ok" ] }, "execution_count": 215, @@ -8002,7 +8002,7 @@ { "data": { "text/plain": [ - "Puzzle 20.1: .023 seconds, answer 1343 ok" + "Puzzle 20.1: .022 seconds, answer 1343 ok" ] }, "execution_count": 217, @@ -8057,7 +8057,7 @@ "source": [ "### Part 1: What is the sum of the complexities of the five codes on your list?\n", "\n", - "The problem is that the numeric keypad is inaccessible, so we have to get a robot to press the buttons, and we have to command the robot's arm by pressing some buttons on a **remote control directional keypad**: arrow keys to move the arm, and the \"`A`\" (activate) button to make the arm press the button it is currently pointing at. Here are the two keypads:\n", + "We know the codes, so what is the difficulty? Unfortunately, the numeric keypad is inaccessible, so we have to get a **robot** to press the buttons, and we have to command the robot's arm by pressing some buttons on a **remote control directional keypad**: arrow keys to move the arm, and the \"`A`\" (activate) button to make the arm press the button it is currently pointing at. Here are the two keypads:\n", "\n", " +---+---+---+ +---+---+\n", " | 7 | 8 | 9 | | ^ | A |\n", @@ -8069,28 +8069,28 @@ " | 0 | A |\n", " +---+---+\n", " \n", - "Long story short: it turns out the directional keypad is *also* inaccessible, and we actually need **three robots**, each pressing buttons on the next keypad, so there are four levels of button pressing all together:\n", + "Long story short: it turns out the robot's remote keypad is *also* inaccessible, and we end up needing **three robots**, each pressing buttons on the next keypad, so there are four levels of button pressing all together:\n", "\n", - "- Level 4: You press some buttons on Robot 3's directional keypad (e.g. \">\"...)\n", - "- Level 2: Robot 2 presses some buttons on Robot 1's directional keypad (e.g. \">\"...)\n", + "- Robot 2 presses some buttons on Robot 1's remote keypad (e.g. \"'])" ] }, + { + "cell_type": "markdown", + "id": "486ae303-36cf-4750-965b-3402eec2b625", + "metadata": {}, + "source": [ + "Now I can compute the possible paths from any starting key to any destination key on a keypad, and press the destination key. There will be either one or two paths, depending on whether one of them hits the `avoid` spot." + ] + }, { "cell_type": "code", "execution_count": 222, @@ -8119,7 +8127,7 @@ "outputs": [], "source": [ "def possible_paths(key1, key2, keypad) -> Iterable[str]:\n", - " \"\"\"Should we try, e.g. \">>^\" or \"^>>\", or both, to get from pos1 to pos2 on keypad?\"\"\"\n", + " \"\"\"Should we try, e.g. \">>^\" or \"^>>\", or both, to get from key1 to key2 on keypad?\"\"\"\n", " pos1, pos2 = keypad[key1], keypad[key2]\n", " (dx, dy) = sub(pos2, pos1)\n", " horizontal = abs(dx) * ('>' if dx > 0 else '<')\n", @@ -8132,223 +8140,147 @@ }, { "cell_type": "code", - "execution_count": 223, + "execution_count": 446, "id": "391f6120-6373-43f2-b697-585c90e45e54", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['>>vvA', 'vv>>A']" - ] - }, - "execution_count": 223, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "list(possible_paths('7', '3', numeric_keypad))" + "assert list(possible_paths('A', '7', numeric_keypad)) == ['^^^<vvvA', 'vvv>A']\n", + "assert list(possible_paths('v', 'A', remote_keypad)) == ['>^A', '^>A']" ] }, { - "cell_type": "code", - "execution_count": 224, - "id": "aec8849e-5fe7-47ab-9569-7fcf4f3ede17", + "cell_type": "markdown", + "id": "74f1f872-5c0c-4baa-a941-d910dc9c1048", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['>>vvvA']" - ] - }, - "execution_count": 224, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "list(possible_paths('7', 'A', numeric_keypad))" + "We need to compute the complexity:" ] }, { "cell_type": "code", - "execution_count": 225, - "id": "9f5fe5bb-de7c-435d-a912-d80a6c4e5de2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ok'" - ] - }, - "execution_count": 225, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "def min_keypresses(code, num_remotes, remote_keypad=remote_keypad, numeric_keypad=numeric_keypad):\n", - " \"\"\"The number of keypresses to type `code`, going through `num_remotes`.\"\"\"\n", - " def total_presses(level: int, keys: str) -> int:\n", - " return sum(cached_lengths[(level, key1, key2)] \n", - " for key1, key2 in sliding_window('A' + keys, 2))\n", - " ## Initializing the cached_lengths[level, position1, position2] dict\n", - " cached_lengths = {(0, key1, key2): 1 for key1 in remote_keypad for key2 in remote_keypad}\n", - " for level in range(1, num_remotes + 1):\n", - " keypad = numeric_keypad if level == num_remotes else remote_keypad\n", - " for key1 in keypad:\n", - " for key2 in keypad:\n", - " paths = possible_paths(key1, key2, keypad)\n", - " cached_lengths[(level, key1, key2)] = min(total_presses(level - 1, path) for path in paths)\n", - " ## Go through the cache, finding the shortest total number of presses\n", - " return total_presses(level, code)\n", - "\n", - "part_1 = sum(min_keypresses(code, 3) * int(code[:-1]) for code in codes)\n", - "assert part_1 == 205160\n", - "part_2 = sum(min_keypresses(code, 26) * int(code[:-1]) for code in codes)\n", - "assert part_2 == 252473394928452\n", - "'ok'" - ] - }, - { - "cell_type": "code", - "execution_count": 226, + "execution_count": 449, "id": "1e2e8c59-744f-4f36-9251-c8ea5fd60aed", "metadata": {}, "outputs": [], "source": [ - "def complexity(code, presses: int): \n", - " \"\"\"The integer part of the code times the number of keypresses.\"\"\"\n", - " return int(cat(digits(code))) * presses" + "def complexity(code, num_presses: int): \n", + " \"\"\"The integer part of the code times the (niminimum) number of key presses.\"\"\"\n", + " return int(cat(digits(code))) * num_presses" ] }, { - "cell_type": "code", - "execution_count": 227, - "id": "cfd67700-2b5c-4f2f-a631-382816a30ebf", + "cell_type": "markdown", + "id": "975b5719-9afc-4b0a-9e07-c1c2b38059f7", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ok'" - ] - }, - "execution_count": 227, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "def min_keypresses(code: str, levels: int, remote_keypad=remote_keypad, numeric_keypad=numeric_keypad):\n", - " \"\"\"The number of keypresses to type `code`, going through `levels`.\"\"\"\n", - " def total_presses(keys: str, level: int) -> int:\n", - " return sum(cached_lengths[(level, key1, key2)] \n", - " for key1, key2 in sliding_window('A' + keys, 2))\n", - " ## Initializing the cached_lengths[level, position1, position2] dict\n", - " cached_lengths = {(0, key1, key2): 1 for key1 in remote_keypad for key2 in remote_keypad}\n", - " for level in range(1, levels):\n", - " keypad = numeric_keypad if level == levels - 1 else remote_keypad\n", - " for key1 in keypad:\n", - " for key2 in keypad:\n", - " paths = possible_paths(key1, key2, keypad)\n", - " cached_lengths[(level, key1, key2)] = min(total_presses(path, level - 1) for path in paths)\n", - " ## Go through the cache, finding the shortest total number of presses\n", - " return total_presses(code, levels - 1)\n", - "\n", - "part_1 = sum(min_keypresses(code, 4) * int(code[:-1]) for code in codes)\n", - "assert part_1 == 205160\n", - "part_2 = sum(min_keypresses(code, 27) * int(code[:-1]) for code in codes)\n", - "assert part_2 == 252473394928452\n", - "'ok'" + "And here's how we compute the minimum number of keypresses. Normally I would do this with a `@cache` decorator, but I was encountering **bugs** doing that and got confused, so I refactored to explicitly create a cache of path lengths saying how many presses it takes at each level to command a single button press, getting you from the start button to the destination button. This made debugging slightly easier for me, or maybe it was just starting over that made it easier." ] }, { "cell_type": "code", - "execution_count": 228, + "execution_count": 489, "id": "704ade67-31e6-4f39-b48c-0a7185c42c48", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ok'" - ] - }, - "execution_count": 228, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "def min_keypresses(code: str, levels: int) -> int:\n", + "def min_keypresses(code: str, levels: int, numeric_keypad=numeric_keypad, remote_keypad=remote_keypad) -> int:\n", " \"\"\"The number of keypresses to type `code`, going through `levels`.\"\"\"\n", " def total_presses(keys: str, level: int) -> int:\n", - " return sum(cached_lengths[(level, key1, key2)] \n", + " return sum(one_button_path_lengths[level, key1, key2] \n", " for key1, key2 in sliding_window('A' + keys, 2))\n", - " ## Initializing the cached_lengths[level, position1, position2] dict\n", - " cached_lengths = {(0, key1, key2): 1 for key1 in remote_keypad for key2 in remote_keypad}\n", + " ## Initializing the one_button_path_lengths[level, key1, key2] dict\n", + " one_button_path_lengths = {(0, key1, key2): 1\n", + " for key1 in remote_keypad for key2 in remote_keypad}\n", " for level in range(1, levels):\n", " keypad = numeric_keypad if level == levels - 1 else remote_keypad\n", " for key1 in keypad:\n", " for key2 in keypad:\n", " paths = possible_paths(key1, key2, keypad)\n", - " cached_lengths[(level, key1, key2)] = min(total_presses(path, level - 1) for path in paths)\n", - " ## Go through the cache, finding the shortest total number of presses\n", - " return total_presses(code, levels - 1)\n", - "\n", - "part_1 = sum(min_keypresses(code, 4) * int(code[:-1]) for code in codes)\n", - "assert part_1 == 205160\n", - "part_2 = sum(min_keypresses(code, 27) * int(code[:-1]) for code in codes)\n", - "assert part_2 == 252473394928452\n", - "'ok'" + " one_button_path_lengths[level, key1, key2] = min(total_presses(path, level - 1) for path in paths)\n", + " ## The cache is built, so just add up the one_button_path_lengths.\n", + " return total_presses(code, levels - 1)" ] }, { "cell_type": "code", - "execution_count": 229, + "execution_count": 491, + "id": "4d8c8659-52d3-4349-8465-7003e880502f", + "metadata": {}, + "outputs": [], + "source": [ + "assert list(sliding_window('A029A', 2)) == ['A0', '02', '29', '9A'] # All the start+destination pairs from the code." + ] + }, + { + "cell_type": "markdown", + "id": "696ad2eb-244a-4ed1-ac0b-d40a0556090f", + "metadata": {}, + "source": [ + "Here is the answer, which turns out to be a fairly small number:" + ] + }, + { + "cell_type": "code", + "execution_count": 493, "id": "393a8c6b-6a1c-4495-aad5-92f48711fbf1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Puzzle 21.1: .002 seconds, answer 205160 ok" + "Puzzle 21.1: .004 seconds, answer 205160 ok" ] }, - "execution_count": 229, + "execution_count": 493, "metadata": {}, "output_type": "execute_result" } ], "source": [ "answer(21.1, 205160, lambda:\n", - " sum(complexity(code, min_keypresses(code, 4)) for code in codes))" + " sum(complexity(code, min_keypresses(code, levels=4)) for code in codes))" + ] + }, + { + "cell_type": "markdown", + "id": "2a16c8f8-e1e5-47f8-b6c6-4a7500a457e6", + "metadata": {}, + "source": [ + "### Part 2: Now, what is the sum of the complexities of the five codes on your list?\n", + "\n", + "As I suspected, Part 2 gets us into the ridiculous number of button presses. The problem is the same, but now there are **27** levels, not 4. No new code, just sum the complexity of the `min_keypresses` again:" ] }, { "cell_type": "code", - "execution_count": 230, + "execution_count": 495, "id": "563c5959-692d-4368-8c0b-469fa0142678", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Puzzle 21.2: .008 seconds, answer 252473394928452 ok" + "Puzzle 21.2: .016 seconds, answer 252473394928452 ok" ] }, - "execution_count": 230, + "execution_count": 495, "metadata": {}, "output_type": "execute_result" } ], "source": [ "answer(21.2, 252473394928452, lambda:\n", - " sum(complexity(code, min_keypresses(code, 27)) for code in codes))" + " sum(complexity(code, min_keypresses(code, levels=27)) for code in codes))" + ] + }, + { + "cell_type": "markdown", + "id": "1cf2d848-2f43-48dc-8862-493cebd94558", + "metadata": {}, + "source": [ + "If we could press one button per microsecond, it would only take 8 years to do this number of button presses." ] }, { @@ -8363,7 +8295,7 @@ }, { "cell_type": "code", - "execution_count": 232, + "execution_count": 230, "id": "2c1e7612-4ec5-4ce1-b591-5c3a14f8ea61", "metadata": {}, "outputs": [ @@ -8414,7 +8346,7 @@ }, { "cell_type": "code", - "execution_count": 234, + "execution_count": 232, "id": "3807adbc-261a-4108-88ba-6e2b061526b5", "metadata": {}, "outputs": [], @@ -8430,17 +8362,17 @@ }, { "cell_type": "code", - "execution_count": 235, + "execution_count": 233, "id": "fce754cd-f6da-4e7d-b406-3314c9c28ca8", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Puzzle 22.1: .321 seconds, answer 14273043166 ok" + "Puzzle 22.1: .314 seconds, answer 14273043166 ok" ] }, - "execution_count": 235, + "execution_count": 233, "metadata": {}, "output_type": "execute_result" } @@ -8484,7 +8416,7 @@ }, { "cell_type": "code", - "execution_count": 237, + "execution_count": 235, "id": "cbbb4793-b13d-4a95-ba03-673b3ebaa229", "metadata": {}, "outputs": [], @@ -8517,17 +8449,17 @@ }, { "cell_type": "code", - "execution_count": 238, + "execution_count": 236, "id": "34eaf7fe-fe9b-4858-b1e8-e4c3713ea093", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Puzzle 22.2: 1.265 seconds, answer 1667 ok" + "Puzzle 22.2: 1.259 seconds, answer 1667 ok" ] }, - "execution_count": 238, + "execution_count": 236, "metadata": {}, "output_type": "execute_result" } @@ -8547,7 +8479,7 @@ }, { "cell_type": "code", - "execution_count": 240, + "execution_count": 238, "id": "a2da8c78-d240-4c52-a83a-f3599f4f69a4", "metadata": {}, "outputs": [ @@ -8557,7 +8489,7 @@ "(-3, 2, -1, 2)" ] }, - "execution_count": 240, + "execution_count": 238, "metadata": {}, "output_type": "execute_result" } @@ -8578,7 +8510,7 @@ }, { "cell_type": "code", - "execution_count": 242, + "execution_count": 240, "id": "9de3f365-c546-494a-a18c-2ae58d88792b", "metadata": {}, "outputs": [ @@ -8608,7 +8540,7 @@ }, { "cell_type": "code", - "execution_count": 244, + "execution_count": 242, "id": "85f5b145-8c5e-448c-8b45-ad5750252ff2", "metadata": {}, "outputs": [ @@ -8659,7 +8591,7 @@ }, { "cell_type": "code", - "execution_count": 246, + "execution_count": 244, "id": "289d2325-1e58-41f5-b4b2-b90ae26e7887", "metadata": {}, "outputs": [], @@ -8684,7 +8616,7 @@ }, { "cell_type": "code", - "execution_count": 247, + "execution_count": 245, "id": "6425577d-4ca9-45de-9698-cd9b026f7ce6", "metadata": {}, "outputs": [ @@ -8694,7 +8626,7 @@ "Puzzle 23.1: .001 seconds, answer 1170 ok" ] }, - "execution_count": 247, + "execution_count": 245, "metadata": {}, "output_type": "execute_result" } @@ -8716,7 +8648,7 @@ }, { "cell_type": "code", - "execution_count": 249, + "execution_count": 247, "id": "88811073-22b2-4378-afa5-9d38462c63b5", "metadata": {}, "outputs": [], @@ -8739,7 +8671,7 @@ }, { "cell_type": "code", - "execution_count": 250, + "execution_count": 248, "id": "0b5f08ac-18e2-4933-9737-cdbc842c5809", "metadata": {}, "outputs": [ @@ -8749,7 +8681,7 @@ "Puzzle 23.2: .003 seconds, answer bo,dd,eq,ik,lo,lu,ph,ro,rr,rw,uo,wx,yg ok" ] }, - "execution_count": 250, + "execution_count": 248, "metadata": {}, "output_type": "execute_result" } @@ -8773,7 +8705,7 @@ }, { "cell_type": "code", - "execution_count": 252, + "execution_count": 250, "id": "47421581-71df-4c72-a62e-c40d0596fdbb", "metadata": {}, "outputs": [ @@ -8836,7 +8768,7 @@ }, { "cell_type": "code", - "execution_count": 254, + "execution_count": 252, "id": "a9a4780f-6033-452f-b49c-74b97c9e2440", "metadata": {}, "outputs": [], @@ -8858,7 +8790,7 @@ }, { "cell_type": "code", - "execution_count": 255, + "execution_count": 253, "id": "72437439-dddf-4202-9944-36e796800304", "metadata": {}, "outputs": [ @@ -8868,7 +8800,7 @@ "Puzzle 24.1: .001 seconds, answer 36035961805936 ok" ] }, - "execution_count": 255, + "execution_count": 253, "metadata": {}, "output_type": "execute_result" } @@ -8915,7 +8847,7 @@ }, { "cell_type": "code", - "execution_count": 258, + "execution_count": 256, "id": "3b41a166-d33b-402b-971b-1dc1d33135ec", "metadata": {}, "outputs": [ @@ -8925,7 +8857,7 @@ "Counter({'AND': 89, 'XOR': 89, 'OR': 44})" ] }, - "execution_count": 258, + "execution_count": 256, "metadata": {}, "output_type": "execute_result" } @@ -8946,7 +8878,7 @@ }, { "cell_type": "code", - "execution_count": 260, + "execution_count": 258, "id": "ec8d86d4-8caf-40f2-b516-c7da4acbda19", "metadata": {}, "outputs": [], @@ -8978,7 +8910,7 @@ }, { "cell_type": "code", - "execution_count": 262, + "execution_count": 260, "id": "2a06af7f-2b9a-4b1f-b9dd-9ec6fb94a1e6", "metadata": {}, "outputs": [], @@ -9019,7 +8951,7 @@ }, { "cell_type": "code", - "execution_count": 263, + "execution_count": 261, "id": "e9b87c38-f67c-4948-9af6-251021747e9d", "metadata": {}, "outputs": [ @@ -9029,7 +8961,7 @@ "Puzzle 24.2: .000 seconds, answer jqf,mdd,skh,wpd,wts,z11,z19,z37 ok" ] }, - "execution_count": 263, + "execution_count": 261, "metadata": {}, "output_type": "execute_result" } @@ -9053,7 +8985,7 @@ }, { "cell_type": "code", - "execution_count": 265, + "execution_count": 263, "id": "f5971853-7139-4f17-bdc5-6c51e12a928d", "metadata": {}, "outputs": [ @@ -9112,7 +9044,7 @@ }, { "cell_type": "code", - "execution_count": 267, + "execution_count": 265, "id": "5302ac58-91fc-475a-83d9-cea91457df3b", "metadata": {}, "outputs": [], @@ -9134,7 +9066,7 @@ }, { "cell_type": "code", - "execution_count": 268, + "execution_count": 266, "id": "c415f5c1-76c3-486c-9075-c46a5a8c5bcb", "metadata": {}, "outputs": [], @@ -9144,17 +9076,17 @@ }, { "cell_type": "code", - "execution_count": 269, + "execution_count": 267, "id": "89c28b74-ed31-4bb5-b463-7177952a95ae", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Puzzle 25.1: .022 seconds, answer 3196 ok" + "Puzzle 25.1: .021 seconds, answer 3196 ok" ] }, - "execution_count": 269, + "execution_count": 267, "metadata": {}, "output_type": "execute_result" } @@ -9176,7 +9108,7 @@ }, { "cell_type": "code", - "execution_count": 271, + "execution_count": 269, "id": "34813fc9-a000-4cd8-88ae-692851b3242c", "metadata": {}, "outputs": [ @@ -9190,53 +9122,53 @@ "Puzzle 2.2: .002 seconds, answer 328 ok\n", "Puzzle 3.1: .001 seconds, answer 156388521 ok\n", "Puzzle 3.2: .000 seconds, answer 75920122 ok\n", - "Puzzle 4.1: .033 seconds, answer 2401 ok\n", + "Puzzle 4.1: .032 seconds, answer 2401 ok\n", "Puzzle 4.2: .026 seconds, answer 1822 ok\n", "Puzzle 5.1: .001 seconds, answer 5762 ok\n", "Puzzle 5.2: .001 seconds, answer 4130 ok\n", "Puzzle 6.1: .002 seconds, answer 5329 ok\n", - "Puzzle 6.2: 1.967 seconds, answer 2162 ok\n", - "Puzzle 7.1: .013 seconds, answer 1985268524462 ok\n", - "Puzzle 7.2: .660 seconds, answer 150077710195188 ok\n", + "Puzzle 6.2: 1.942 seconds, answer 2162 ok\n", + "Puzzle 7.1: .014 seconds, answer 1985268524462 ok\n", + "Puzzle 7.2: .646 seconds, answer 150077710195188 ok\n", "Puzzle 8.1: .003 seconds, answer 220 ok\n", "Puzzle 8.2: .003 seconds, answer 813 ok\n", - "Puzzle 9.1: .019 seconds, answer 6332189866718 ok\n", - "Puzzle 9.2: 2.754 seconds, answer 6353648390778 ok\n", + "Puzzle 9.1: .020 seconds, answer 6332189866718 ok\n", + "Puzzle 9.2: 2.680 seconds, answer 6353648390778 ok\n", "Puzzle 10.1: .005 seconds, answer 744 ok\n", "Puzzle 10.2: .006 seconds, answer 1651 ok\n", "Puzzle 11.1: .002 seconds, answer 194482 ok\n", - "Puzzle 11.2: .061 seconds, answer 232454623677743 ok\n", - "Puzzle 12.1: .052 seconds, answer 1402544 ok\n", + "Puzzle 11.2: .060 seconds, answer 232454623677743 ok\n", + "Puzzle 12.1: .051 seconds, answer 1402544 ok\n", "Puzzle 12.2: .042 seconds, answer 862486 ok\n", "Puzzle 13.1: .000 seconds, answer 29598 ok\n", "Puzzle 13.2: .000 seconds, answer 93217456941970 ok\n", "Puzzle 14.1: .000 seconds, answer 216027840 ok\n", - "Puzzle 14.2: 1.869 seconds, answer 6876 ok\n", - "Puzzle 15.1: .029 seconds, answer 1563092 ok\n", + "Puzzle 14.2: 1.825 seconds, answer 6876 ok\n", + "Puzzle 15.1: .028 seconds, answer 1563092 ok\n", "Puzzle 15.2: .041 seconds, answer 1582688 ok\n", - "Puzzle 16.1: .147 seconds, answer 103512 ok\n", - "Puzzle 16.2: .852 seconds, answer 554 ok\n", + "Puzzle 16.1: .144 seconds, answer 103512 ok\n", + "Puzzle 16.2: .846 seconds, answer 554 ok\n", "Puzzle 17.1: .000 seconds, answer 2,1,0,1,7,2,5,0,3 ok\n", - "Puzzle 17.2: .023 seconds, answer 267265166222235 ok\n", + "Puzzle 17.2: .024 seconds, answer 267265166222235 ok\n", "Puzzle 18.1: .014 seconds, answer 344 ok\n", "Puzzle 18.2: .032 seconds, answer 46,18 ok\n", "Puzzle 19.1: .004 seconds, answer 242 ok\n", - "Puzzle 19.2: .187 seconds, answer 595975512785325 ok\n", - "Puzzle 20.1: .023 seconds, answer 1343 ok\n", - "Puzzle 20.2: .770 seconds, answer 982891 ok\n", + "Puzzle 19.2: .184 seconds, answer 595975512785325 ok\n", + "Puzzle 20.1: .022 seconds, answer 1343 ok\n", + "Puzzle 20.2: .756 seconds, answer 982891 ok\n", "Puzzle 21.1: .002 seconds, answer 205160 ok\n", "Puzzle 21.2: .008 seconds, answer 252473394928452 ok\n", - "Puzzle 22.1: .321 seconds, answer 14273043166 ok\n", - "Puzzle 22.2: 1.265 seconds, answer 1667 ok\n", + "Puzzle 22.1: .314 seconds, answer 14273043166 ok\n", + "Puzzle 22.2: 1.259 seconds, answer 1667 ok\n", "Puzzle 23.1: .001 seconds, answer 1170 ok\n", "Puzzle 23.2: .003 seconds, answer bo,dd,eq,ik,lo,lu,ph,ro,rr,rw,uo,wx,yg ok\n", "Puzzle 24.1: .001 seconds, answer 36035961805936 ok\n", "Puzzle 24.2: .000 seconds, answer jqf,mdd,skh,wpd,wts,z11,z19,z37 ok\n", - "Puzzle 25.1: .022 seconds, answer 3196 ok\n", + "Puzzle 25.1: .021 seconds, answer 3196 ok\n", "\n", "Correct: 49/49\n", "\n", - "Time in seconds: 0.008 median, 0.230 mean, 11.268 total.\n" + "Time in seconds: 0.008 median, 0.226 mean, 11.069 total.\n" ] } ],