diff --git a/ipynb/Advent-2024.ipynb b/ipynb/Advent-2024.ipynb index 9b5f41e..f3d8da3 100644 --- a/ipynb/Advent-2024.ipynb +++ b/ipynb/Advent-2024.ipynb @@ -136,7 +136,7 @@ { "data": { "text/plain": [ - "Puzzle 1.1: .0001 seconds, answer 1830467 ok" + "Puzzle 1.1: .0002 seconds, answer 1830467 ok" ] }, "execution_count": 8, @@ -334,7 +334,7 @@ { "data": { "text/plain": [ - "Puzzle 2.2: .0022 seconds, answer 328 ok" + "Puzzle 2.2: .0021 seconds, answer 328 ok" ] }, "execution_count": 19, @@ -553,7 +553,7 @@ { "data": { "text/plain": [ - "Puzzle 4.1: .0339 seconds, answer 2401 ok" + "Puzzle 4.1: .0328 seconds, answer 2401 ok" ] }, "execution_count": 32, @@ -608,7 +608,7 @@ { "data": { "text/plain": [ - "Puzzle 4.2: .0267 seconds, answer 1822 ok" + "Puzzle 4.2: .0266 seconds, answer 1822 ok" ] }, "execution_count": 35, @@ -628,11 +628,11 @@ "source": [ "# [Day 5](https://adventofcode.com/2024/day/5): Print Queue\n", "\n", - "Today's puzzle involves a **sleigh launch safety manual** that needs to be updated. The day's input is in two parts: the first a set of **rules** such as \"47|53\", which means that page 47 must be printed before page 53; and the second a list of **updates** of the form \"75,47,61,53,29\", meaning that those pages are to be printed in that order.\n", + "Today's puzzle involves a **sleigh launch safety manual** that needs to be updated. The day's input is in two sections: the first a set of **rules** such as \"47|53\", which means that page 47 must be printed before page 53; and the second a list of **updates** of the form \"75,47,61,53,29\", meaning that those pages are to be printed in that order.\n", "\n", "\n", "\n", - "I mostly like my `parse` function, but I admit it is not ideal when an input file has two parts like this. I'll parse the two parts into paragraphs, and then call `parse` again on each paragraph:" + "I mostly like my `parse` function, but I admit it is not ideal when an input file has two sections like this. I'll parse the two sections as paragraphs, and then call `parse` again on each paragraph:" ] }, { @@ -993,7 +993,7 @@ { "data": { "text/plain": [ - "Puzzle 6.2: 1.9577 seconds, answer 2162 ok" + "Puzzle 6.2: 1.9431 seconds, answer 2162 ok" ] }, "execution_count": 55, @@ -1171,7 +1171,7 @@ { "data": { "text/plain": [ - "Puzzle 7.2: .7986 seconds, answer 150077710195188 ok" + "Puzzle 7.2: .7898 seconds, answer 150077710195188 ok" ] }, "execution_count": 66, @@ -1267,7 +1267,7 @@ { "data": { "text/plain": [ - "Puzzle 8.1: .0028 seconds, answer 220 ok" + "Puzzle 8.1: .0026 seconds, answer 220 ok" ] }, "execution_count": 71, @@ -1322,7 +1322,7 @@ { "data": { "text/plain": [ - "Puzzle 8.1: .0026 seconds, answer 220 ok" + "Puzzle 8.1: .0028 seconds, answer 220 ok" ] }, "execution_count": 74, @@ -1344,7 +1344,7 @@ { "data": { "text/plain": [ - "Puzzle 8.2: .0033 seconds, answer 813 ok" + "Puzzle 8.2: .0029 seconds, answer 813 ok" ] }, "execution_count": 75, @@ -1457,7 +1457,7 @@ { "data": { "text/plain": [ - "Puzzle 9.1: .0201 seconds, answer 6332189866718 ok" + "Puzzle 9.1: .0194 seconds, answer 6332189866718 ok" ] }, "execution_count": 81, @@ -1537,7 +1537,7 @@ { "data": { "text/plain": [ - "Puzzle 9.2: 2.7191 seconds, answer 6353648390778 ok" + "Puzzle 9.2: 2.6750 seconds, answer 6353648390778 ok" ] }, "execution_count": 84, @@ -1646,7 +1646,7 @@ { "data": { "text/plain": [ - "Puzzle 10.1: .0050 seconds, answer 744 ok" + "Puzzle 10.1: .0048 seconds, answer 744 ok" ] }, "execution_count": 90, @@ -1697,7 +1697,7 @@ { "data": { "text/plain": [ - "Puzzle 10.2: .0062 seconds, answer 1651 ok" + "Puzzle 10.2: .0059 seconds, answer 1651 ok" ] }, "execution_count": 93, @@ -1839,7 +1839,7 @@ { "data": { "text/plain": [ - "Puzzle 11.1: .0681 seconds, answer 194482 ok" + "Puzzle 11.1: .0678 seconds, answer 194482 ok" ] }, "execution_count": 100, @@ -1922,7 +1922,7 @@ { "data": { "text/plain": [ - "Puzzle 11.2: .0595 seconds, answer 232454623677743 ok" + "Puzzle 11.2: .0586 seconds, answer 232454623677743 ok" ] }, "execution_count": 105, @@ -2054,7 +2054,7 @@ { "data": { "text/plain": [ - "Puzzle 12.1: .0331 seconds, answer 1402544 ok" + "Puzzle 12.1: .0332 seconds, answer 1402544 ok" ] }, "execution_count": 113, @@ -2127,7 +2127,7 @@ { "data": { "text/plain": [ - "Puzzle 12.1: .0308 seconds, answer 1402544 ok" + "Puzzle 12.1: .0304 seconds, answer 1402544 ok" ] }, "execution_count": 116, @@ -2149,7 +2149,7 @@ { "data": { "text/plain": [ - "Puzzle 12.2: .0423 seconds, answer 862486 ok" + "Puzzle 12.2: .0414 seconds, answer 862486 ok" ] }, "execution_count": 117, @@ -2269,7 +2269,7 @@ { "data": { "text/plain": [ - "Puzzle 13.1: .0107 seconds, answer 29598 ok" + "Puzzle 13.1: .0104 seconds, answer 29598 ok" ] }, "execution_count": 122, @@ -2781,42 +2781,42 @@ "\n", "\n", "
\n", - " \n", + " \n", "
\n", - " \n", + " oninput=\"anim1a607d31ddad4d7889fd0eb35bbee10b.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_imge68603ecbe714d0aacd3edf31873c115\";\n", - " var slider_id = \"_anim_slidere68603ecbe714d0aacd3edf31873c115\";\n", - " var loop_select_id = \"_anim_loop_selecte68603ecbe714d0aacd3edf31873c115\";\n", + " var img_id = \"_anim_img1a607d31ddad4d7889fd0eb35bbee10b\";\n", + " var slider_id = \"_anim_slider1a607d31ddad4d7889fd0eb35bbee10b\";\n", + " var loop_select_id = \"_anim_loop_select1a607d31ddad4d7889fd0eb35bbee10b\";\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", - " anime68603ecbe714d0aacd3edf31873c115 = new Animation(frames, img_id, slider_id, 200.0,\n", + " anim1a607d31ddad4d7889fd0eb35bbee10b = 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=\"anim5d103dc2b0f34cb6b7c273a53699d621.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_img9a2476b9e7bf4f5e9a2e2f3b191f3f0b\";\n", - " var slider_id = \"_anim_slider9a2476b9e7bf4f5e9a2e2f3b191f3f0b\";\n", - " var loop_select_id = \"_anim_loop_select9a2476b9e7bf4f5e9a2e2f3b191f3f0b\";\n", + " var img_id = \"_anim_img5d103dc2b0f34cb6b7c273a53699d621\";\n", + " var slider_id = \"_anim_slider5d103dc2b0f34cb6b7c273a53699d621\";\n", + " var loop_select_id = \"_anim_loop_select5d103dc2b0f34cb6b7c273a53699d621\";\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", - " anim9a2476b9e7bf4f5e9a2e2f3b191f3f0b = new Animation(frames, img_id, slider_id, 200.0,\n", + " anim5d103dc2b0f34cb6b7c273a53699d621 = 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.8663 seconds, answer 6876 ok" + "Puzzle 14.2: 1.8659 seconds, answer 6876 ok" ] }, "execution_count": 145, @@ -6624,7 +6624,7 @@ "source": [ "# [Day 15](https://adventofcode.com/2024/day/15): Warehouse Woes\n", "\n", - "Today's input is in two parts: the first part is a grid map describing a warehouse with walls (`#`) and boxes (`O`) and one robot (`@`). The second part is a set of instructions for how the robot moves (arrows). I'll parse the two parts into paragraphs, then parse each paragraph:" + "Today's input is in two sections: the first section is a grid map describing a warehouse with walls (`#`) and boxes (`O`) and one robot (`@`). The second part is a set of instructions for how the robot moves (arrows). I'll parse the two sections as paragraphs, then parse each paragraph:" ] }, { @@ -6723,7 +6723,7 @@ { "data": { "text/plain": [ - "Puzzle 15.1: .0241 seconds, answer 1563092 ok" + "Puzzle 15.1: .0289 seconds, answer 1563092 ok" ] }, "execution_count": 150, @@ -6800,7 +6800,7 @@ { "data": { "text/plain": [ - "Puzzle 15.1: .0290 seconds, answer 1563092 ok" + "Puzzle 15.1: .0335 seconds, answer 1563092 ok" ] }, "execution_count": 153, @@ -6822,7 +6822,7 @@ { "data": { "text/plain": [ - "Puzzle 15.2: .0419 seconds, answer 1582688 ok" + "Puzzle 15.2: .0496 seconds, answer 1582688 ok" ] }, "execution_count": 154, @@ -6979,7 +6979,7 @@ { "data": { "text/plain": [ - "Puzzle 16.1: .1470 seconds, answer 103512 ok" + "Puzzle 16.1: .1765 seconds, answer 103512 ok" ] }, "execution_count": 162, @@ -7043,7 +7043,7 @@ { "data": { "text/plain": [ - "Puzzle 16.2: .8517 seconds, answer 554 ok" + "Puzzle 16.2: .8575 seconds, answer 554 ok" ] }, "execution_count": 165, @@ -7339,7 +7339,7 @@ { "data": { "text/plain": [ - "Puzzle 17.2: .0039 seconds, answer 267265166222235 ok" + "Puzzle 17.2: .0235 seconds, answer 267265166222235 ok" ] }, "execution_count": 179, @@ -7448,7 +7448,7 @@ { "data": { "text/plain": [ - "Puzzle 18.1: .0141 seconds, answer 344 ok" + "Puzzle 18.1: .0138 seconds, answer 344 ok" ] }, "execution_count": 184, @@ -7468,10 +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 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", + "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 two 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. **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 " + "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!**" ] }, { @@ -7481,17 +7480,16 @@ "metadata": {}, "outputs": [], "source": [ - "def memory_blocker(falling_bytes) -> Point:\n", + "def memory_blocker(falling_bytes, good=1024) -> Point:\n", " \"\"\"Which falling byte is the first to block a path to the exit? Do binary search.\"\"\"\n", - " good = 0\n", - " bad = len(falling_bytes) - 1\n", + " bad = len(falling_bytes)\n", " while bad - good > 1:\n", " mid = (good + bad) // 2\n", - " if memory_path(falling_bytes[:mid + 1]) == search_failure:\n", + " if memory_path(falling_bytes[:mid]) == search_failure:\n", " bad = mid\n", " else:\n", " good = mid\n", - " return falling_bytes[bad]" + " return falling_bytes[bad - 1]" ] }, { @@ -7503,7 +7501,7 @@ { "data": { "text/plain": [ - "Puzzle 18.2: .0359 seconds, answer 46,18 ok" + "Puzzle 18.2: .0321 seconds, answer 46,18 ok" ] }, "execution_count": 187, @@ -7521,7 +7519,146 @@ "id": "552f1c6e-052e-43d0-b13f-e8f66f274d63", "metadata": {}, "source": [ - "I admit I initially had an off-by-one **bug** here. I wanted `bad` to be an index into the falling bytes, but it is also natural to have it be the end of a range; I was confused about my choice." + "I admit I initially had an off-by-one **bug** here. I was inconsistent on whether `bad` should be an index into the falling bytes, or the stop of a slice.\n", + "\n", + "I realize that for Part 1 I should have had separate functions for making the grid and solving it; then in Part 2 I could have incrementally modified the grid each time rather than creating a whole new Grid (and Problem). But it runs in under 1/10 second, so it is not worth changing it." + ] + }, + { + "cell_type": "markdown", + "id": "702d6ea3-bcb1-4c90-8d67-9e686cd0155f", + "metadata": {}, + "source": [ + "# [Day 19](https://adventofcode.com/2024/day/19): Linen Layout\n", + "\n", + "Today's input is in two sections, the first a list of towel designs (with each letter of a word specifying a color), and the second section a list of desired patterns to be made by adjoining towels." + ] + }, + { + "cell_type": "code", + "execution_count": 190, + "id": "689df92b-92d7-44e6-8b4e-d67bf3f153df", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "────────────────────────────────────────────────────────────────────────────────────────────────────\n", + "Puzzle input ➜ 402 strs:\n", + "────────────────────────────────────────────────────────────────────────────────────────────────────\n", + "rub, wugrr, gww, wgurb, urur, ggb, bw, uubbu, uw, uggru, gwwgrgb, wbbb, rgb, wuuur, bgruggug, ru ...\n", + "\n", + "rurgggubugbuwugbwgggwbwwwrbrbgwwwwuwuugrwbrbwgguwr\n", + "ruurbrwgrurubwrurugubgurgruurwgugwgrwuwbrww\n", + "gwbrwwruwubrwgubggggubwwrurugbbuuugwwburbw\n", + "wwgwugrrrbwbgwburguwgbrgrwurugbbgubuuugbguur\n", + "ubgbbrruwbgbrrgwwwwwrwgggggrwbgwuwgrwrbwbrg\n", + "rurbbgrbwbggugrbwwbwrwuwuwbwwbwugwrubbww\n", + "...\n", + "────────────────────────────────────────────────────────────────────────────────────────────────────\n", + "Parsed representation ➜ 2 tuples:\n", + "────────────────────────────────────────────────────────────────────────────────────────────────────\n", + "('rub', 'wugrr', 'gww', 'wgurb', 'urur', 'ggb', 'bw', 'uubbu', 'uw', 'uggru', 'gwwgrgb', 'wbbb', ...\n", + "('rurgggubugbuwugbwgggwbwwwrbrbgwwwwuwuugrwbrbwgguwr', 'ruurbrwgrurubwrurugubgurgruurwgugwgrwuwb ...\n" + ] + } + ], + "source": [ + "patterns, designs = parse(19, atoms, sections=paragraphs)" + ] + }, + { + "cell_type": "markdown", + "id": "581ff31b-ec09-4ae5-84c7-3b3ffbbd9362", + "metadata": {}, + "source": [ + "### Part 1: How many designs are possible?\n", + "\n", + "The task is to see how many of the designs can posibly be made by concatenating one or more of the patterns (with repetitions allowed). I can do this by checking if some pattern starts the design and recursively checking if the rest of the design is possible:" + ] + }, + { + "cell_type": "code", + "execution_count": 192, + "id": "e0b96545-5f60-4c8e-9a0f-c77608c19128", + "metadata": {}, + "outputs": [], + "source": [ + "def is_possible_design(design, patterns=patterns) -> bool:\n", + " \"\"\"Is it possible to make `design` by concatenating some of the `patterns`?\"\"\"\n", + " return (design == '' \n", + " or any(design.startswith(p) and is_possible_design(design[len(p):], patterns) \n", + " for p in patterns))" + ] + }, + { + "cell_type": "code", + "execution_count": 193, + "id": "3c3fba1b-d3e5-494e-aad0-42ca0566ae1f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Puzzle 19.1: .0397 seconds, answer 242 ok" + ] + }, + "execution_count": 193, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "answer(19.1, 242, lambda:\n", + " quantify(designs, is_possible_design))" + ] + }, + { + "cell_type": "markdown", + "id": "c7a03f27-c1af-4561-a887-ff4f9b7b0b51", + "metadata": {}, + "source": [ + "### Part 2: What do you get if you add up the number of different ways you could make each design?\n", + "\n", + "For Part 2 we need to count all the ways that each design can be made. Since there can be an exponential number of ways for each design, I'm going to `cache` intermediate results. The number of ways is computed by consiering each pattern that starts the design and recursively summing up the count of the number of ways for the rest of the design." + ] + }, + { + "cell_type": "code", + "execution_count": 195, + "id": "77d4fae1-d506-4733-9bb2-467619012f97", + "metadata": {}, + "outputs": [], + "source": [ + "@cache\n", + "def count_ways(design, patterns=patterns) -> int:\n", + " \"\"\"How many ways can the design be made from the patterns?\"\"\"\n", + " return (1 if design == '' else\n", + " sum(count_ways(design[len(p):], patterns)\n", + " for p in patterns if design.startswith(p)))" + ] + }, + { + "cell_type": "code", + "execution_count": 196, + "id": "14116eca-0b0f-484a-a169-9726e4ac7fbf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Puzzle 19.2: .1862 seconds, answer 595975512785325 ok" + ] + }, + "execution_count": 196, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "answer(19.2, 595975512785325, lambda:\n", + " sum(map(count_ways, designs)))" ] }, { @@ -7531,12 +7668,12 @@ "source": [ "# Summary\n", "\n", - "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." + "So far, I've solved all the puzzles. The median run time is about a hundredth of a second, but three problems take over a second." ] }, { "cell_type": "code", - "execution_count": 190, + "execution_count": 198, "id": "34813fc9-a000-4cd8-88ae-692851b3242c", "metadata": {}, "outputs": [ @@ -7544,46 +7681,48 @@ "name": "stdout", "output_type": "stream", "text": [ - "Puzzle 1.1: .0001 seconds, answer 1830467 ok\n", + "Puzzle 1.1: .0002 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: .0022 seconds, answer 328 ok\n", + "Puzzle 2.2: .0021 seconds, answer 328 ok\n", "Puzzle 3.1: .0006 seconds, answer 156388521 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 4.1: .0328 seconds, answer 2401 ok\n", + "Puzzle 4.2: .0266 seconds, answer 1822 ok\n", "Puzzle 5.1: .0007 seconds, answer 5762 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 6.2: 1.9431 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: .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 7.2: .7898 seconds, answer 150077710195188 ok\n", + "Puzzle 8.1: .0028 seconds, answer 220 ok\n", + "Puzzle 8.2: .0029 seconds, answer 813 ok\n", + "Puzzle 9.1: .0194 seconds, answer 6332189866718 ok\n", + "Puzzle 9.2: 2.6750 seconds, answer 6353648390778 ok\n", + "Puzzle 10.1: .0048 seconds, answer 744 ok\n", + "Puzzle 10.2: .0059 seconds, answer 1651 ok\n", "Puzzle 11.1: .0015 seconds, answer 194482 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 11.2: .0586 seconds, answer 232454623677743 ok\n", + "Puzzle 12.1: .0304 seconds, answer 1402544 ok\n", + "Puzzle 12.2: .0414 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.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 14.2: 1.8659 seconds, answer 6876 ok\n", + "Puzzle 15.1: .0335 seconds, answer 1563092 ok\n", + "Puzzle 15.2: .0496 seconds, answer 1582688 ok\n", + "Puzzle 16.1: .1765 seconds, answer 103512 ok\n", + "Puzzle 16.2: .8575 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: .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", + "Puzzle 17.2: .0235 seconds, answer 267265166222235 ok\n", + "Puzzle 18.1: .0138 seconds, answer 344 ok\n", + "Puzzle 18.2: .0321 seconds, answer 46,18 ok\n", + "Puzzle 19.1: .0397 seconds, answer 242 ok\n", + "Puzzle 19.2: .1862 seconds, answer 595975512785325 ok\n", "\n", - "Correct: 36/36\n", + "Correct: 38/38\n", "\n", - "Time in seconds: 0.0056 median, 0.2422 mean, 8.7188 total.\n" + "Time in seconds: 0.0138 median, 0.2351 mean, 8.9351 total.\n" ] } ],