Add files via upload

This commit is contained in:
Peter Norvig authored and GitHub committed 2025-01-02 22:28:17 -08:00
1 parent 1154ddfa28
commit 7443960053
1 file changed
+222 -213
+222 -213
View File
@@ -5,13 +5,13 @@
"id": "4f0ef1f2-0c73-4ef5-b430-48fe4ce450c0",
"metadata": {},
"source": [
"<div style=\"text-align: right\" align=\"right\"><i>Peter Norvig, December 2024</i></div>\n",
"<div style=\"text-align: right\" align=\"right\"><i>Peter Norvig<br>December 2024</i></div>\n",
"\n",
"# Advent of Code 2024\n",
"\n",
"I enjoy doing the [**Advent of Code**](https://adventofcode.com/) (AoC) programming puzzles, so here we go for 2024! This is the 10th year, so congratulations to puzzle creator [**Eric Wastl**](https://adventofcode.com/2024/about). Our old friend [**Gary Grady**](https://find.sciences.social/search/accounts/@garygrady@mastodon.social) is here to provide illustrations:\n",
"\n",
"<a href=\"https://x.com/garyjgrady\"><img src=\"https://pbs.twimg.com/media/Gdp709FW8AAq2_m?format=jpg&name=medium\" width=400 alt=\"GaryJGrady cartoon\"></a>\n",
"<a href=\"https://mastodon.social/@garygrady\"><img src=\"https://pbs.twimg.com/media/Gdp709FW8AAq2_m?format=jpg&name=medium\" width=400 alt=\"GaryJGrady cartoon\"></a>\n",
"\n",
"Even before December 1st I can start by loading up my [**AdventUtils.ipynb**](AdventUtils.ipynb) notebook (same as last time except for the `current_year`):"
]
@@ -631,7 +631,7 @@
{
"data": {
"text/plain": [
"Puzzle 4.1: .022 seconds, answer 2401 ok"
"Puzzle 4.1: .021 seconds, answer 2401 ok"
]
},
"execution_count": 39,
@@ -1082,7 +1082,7 @@
{
"data": {
"text/plain": [
"Puzzle 6.2: 1.967 seconds, answer 2162 ok"
"Puzzle 6.2: 1.932 seconds, answer 2162 ok"
]
},
"execution_count": 63,
@@ -1276,7 +1276,7 @@
{
"data": {
"text/plain": [
"Puzzle 7.2: .799 seconds, answer 150077710195188 ok"
"Puzzle 7.2: .776 seconds, answer 150077710195188 ok"
]
},
"execution_count": 75,
@@ -1327,7 +1327,7 @@
{
"data": {
"text/plain": [
"Puzzle 7.2: .595 seconds, answer 150077710195188 ok"
"Puzzle 7.2: .586 seconds, answer 150077710195188 ok"
]
},
"execution_count": 78,
@@ -1421,7 +1421,7 @@
{
"data": {
"text/plain": [
"Puzzle 8.1: .003 seconds, answer 220 ok"
"Puzzle 8.1: .002 seconds, answer 220 ok"
]
},
"execution_count": 83,
@@ -1475,7 +1475,7 @@
{
"data": {
"text/plain": [
"Puzzle 8.1: .003 seconds, answer 220 ok"
"Puzzle 8.1: .002 seconds, answer 220 ok"
]
},
"execution_count": 86,
@@ -1530,56 +1530,56 @@
"name": "stdout",
"output_type": "stream",
"text": [
"..........E7...xH..s....B.C........4..W..........5\n",
".........4O.T..H3...t..h....3.s..C.3..zo..35b.....\n",
".e.....x..x.7cH.x....k..8....CT...z.o5............\n",
"..........E7...xH..s....B.C........z..W..........5\n",
".........4O.5..H3...t..h....3.s..C.3..zo..35b.....\n",
".e.....x..x.7OH.x....t..8....CT...z.o5............\n",
"5...........XH...s...t.....s...5j...8z.T.3........\n",
"...........EH...ex.Tj3t.E5....3.C....E..k.K....c.w\n",
".e0........Hh...Kb.5.t.cs......O.S..z..k3....9..Eo\n",
"...........EH...ex.Tj3t.E5....3.C....E..k.O....c.w\n",
".30........Hh...Kb.5.t.cs......O.S..z..k3....9..Eo\n",
".......3..H..5.s..x.O..B..........9C3..zcb....o.wX\n",
".......5.H.x.3.......st9..j...4C3j..W..3...o.G....\n",
".5.0....H...E......x.........o...c....z.o......w..\n",
".hH....H.c...sex.7s...kj.3.....b...E.o3..K.....w..\n",
"......H..........67.x.....cO..C3.To.5..8.C..E.K..S\n",
".......5.O.x.3.......st9..3...8C3j..W..3...o.G....\n",
".5.0....H...E......x.........o...c....C.o......w..\n",
".9H....H.c...sex.7s...tj.3.....b...E.o3..K.....w..\n",
"......H..........67.x.....cO..C3.T3.5..8.C..E.w..S\n",
"sW..0H....H...5s.........B6....o..j..Cb.z..c......\n",
".s..HO.....s.HHx...c.xBt....o.......8.....eKCw..S.\n",
"..sH.k..H...s.....H..H.t.o.e.C......3..zT.......X3\n",
"T.Hs.0.....kc.......H7o..4j..H...EW..9..K.z.w..S..\n",
".H..s....T.H.....k.o.5..H.H........j.H..E.G..0....\n",
"H....c.......1E5o.T.x.7k...HC.j.4..b..3C.z.w.HST..\n",
".O....4......oH....x....t..T.k....HS....e08.z.....\n",
".......s..o..........B.7x.........HkT.H0zOw..S....\n",
".s..6O.....s.EHx...c.xBt....o.......8.....e3Cw..S.\n",
"..sH.k..O...s.....H..H.E.o.e.C......3..zT.......X3\n",
"T.Hs.0.....ke.......H7x..4j..H...EO..9..K.z.w..C..\n",
".H..s....T.H.....k.o.5..H.H........3.H..E.G..0....\n",
"H....c.......1E5o.T.x.7x...eC.j.4..b..3C.3.0.HST..\n",
".O....s......oH....x....t..T.k....3S....e08.z.....\n",
".......s..o..........B.7x.........HHT.H0zOw..S....\n",
"...s...os.e......H.......b.C5j.E.3C.j0.K3kHz.T31.J\n",
"..g.o..0.s.....o........tx.........0E....H..S.Hk..\n",
"..g.o..0.s.....E........tx.........0E....H..S.HX..\n",
"so...s....s.....5...H....t....K.30w....3.Cz...H.J.\n",
"....Kg...o.s..........Ex.tx7X..0........wK3S.3..H.\n",
"........0...s6.........Hkx.7.0.3...5Sj.wez.....Jz.\n",
".4.s....g....s..E...BT....wx1E..j.....Kw..S.z8....\n",
"....KS...o.s..........Ex.tx7X..0........9K3S.3..8.\n",
"........0...s6.........Hkx.7.9.3...5Sj.wez.....Jz.\n",
".4.O....e....s..E...BT....wx1E..j.....Kw..S.z8....\n",
".E....O.....K.s..........Ct...38E.j......W..3.J...\n",
"....h...o0.g...s.8.....e.w..xb7.......wT3S8z.....j\n",
"02.8........S...s.wW.0....txTH.......wj...5.cJX..Z\n",
"..J...k.......g4.E.0K...Ct...xW......w.8S.z...3..G\n",
"...0E.e...0......0sk.......t3...H..j.K......JzT...\n",
"..........w....0.gks.....kttE.x777.ww..S...9..GG..\n",
".....O0......0.Tw.5.sE.C..b3K......HG..j.3.JzC..85\n",
"So..2......0......ESgs.....t...x.C.w..S....GG..z..\n",
"....h...o0.g...s.8.....e.w..xb7.......wT3S8C.....j\n",
"02.8........S...s.wW.0....txT3.......wj...5.cJX..Z\n",
"..J...k.......84.E.0K...Ct...xW......w.8S.z...3..G\n",
"...0E.e...0......0sk.......E3...H..j.K......JzT...\n",
"..........w....0.gkB.....kttE.x777.w8..S...9..GG..\n",
".....O0......0.Tw.5.sE.C..b3K......HG..j.3.JzC..35\n",
"S2..2......0......ESg9.....t...x.C.w..S....1G..z..\n",
"B.w4...E.0..........8ws...3.t...1b....H...Jz...X..\n",
"....e.B0.....h.......16g.E....8.x.w.KSjWG.T..XZ...\n",
"6....0..S.4.0.k.........E3..W.........S.jJ.......z\n",
"....e.B0.....h.......1Cs.E....8.x.w.CSjWG.T..XZ...\n",
"6....0..S.1.B.k.........E3..W.........S.jH.......z\n",
"...0...w.6.......WBE...b.st8....wx.7SG....3..z.C..\n",
".0..O.W2..E....0..6..C..3.k.tt.w...x.7..J...H.....\n",
".........T...0..S.......8..6tgB.w.xS...7....z.S...\n",
".0..O.W2..E....0..6..C..3.s.tt.w...x.7..J...H.....\n",
".........T...0..S.......8..6tgB.w.xS...7....z.9...\n",
"..e...............0....E....st...G.K67.J.j....EH..\n",
"...2W...............E8.......s.wg.Sx.b...EB..6....\n",
"........2k..jE0W....503.S.....t.....E.JS...ZX.z.BC\n",
"........28..jE0W....b03.S.....t.....E.JS...3X.z.BC\n",
".....4..k.2..2...B8...h...WjGtwE.S.gx..x..7..T...z\n",
"..oO...k..........2C.3..0.ESt...s....J....j..cg...\n",
"e.....G........8.....S.2.G.k.w..SsK..xg.x.7Jj...W.\n",
"...T....w....jGSE...3......w2..tC.s.J..1.7.......X\n",
".........S.E8....bC..5G.....w..K.2.s..x..g..37.X.9\n",
"...Sk.E...B..2..0..2.....S....t....Js.2.Sb.j.X....\n",
"..oO...k..........2C.3..0.ESt...s....J....j..zg...\n",
"e.....G........8.....E.2.G.t.w..SsK..xg.x.7Jj...W.\n",
"...T....w....jGSE...3......02..6C.b.J..1.7.......X\n",
".........S.E8....bC..5G.....w..K.2.s..x..G..37.X.9\n",
"...Sk.E...B..2..0..2.....S....t....Js.2.Sb.x.X....\n",
".E.......8......B..G..E....w..St.....sGxZ..2g.z...\n",
"4.O..6..G........C3E....W....2..tKJ.g.C..X....Gj2.\n"
"4.O..6..G........C3E....W....2..t0J.g.C..X....Gj2.\n"
]
}
],
@@ -1701,7 +1701,7 @@
{
"data": {
"text/plain": [
"Puzzle 9.1: .020 seconds, answer 6332189866718 ok"
"Puzzle 9.1: .019 seconds, answer 6332189866718 ok"
]
},
"execution_count": 94,
@@ -1995,12 +1995,12 @@
"source": [
"def plot_topo(topo: Grid):\n",
" \"\"\"Show the map with a colormap from blue to red.\"\"\"\n",
" plt.figure()\n",
" scatter = plt.scatter(Xs(topo), Ys(topo), c=list(topo.values()), \n",
" cmap='coolwarm', marker='s', s=12)\n",
" plt.colorbar(scatter, label='Elevation')\n",
" plt.axis('square')\n",
" plt.axis('off')\n",
" plt.show()\n",
"\n",
"plot_topo(topo)"
]
@@ -2177,7 +2177,7 @@
{
"data": {
"text/plain": [
"Puzzle 11.2: .060 seconds, answer 232454623677743 ok"
"Puzzle 11.2: .059 seconds, answer 232454623677743 ok"
]
},
"execution_count": 119,
@@ -2442,7 +2442,7 @@
{
"data": {
"text/plain": [
"Puzzle 12.1: .051 seconds, answer 1402544 ok"
"Puzzle 12.1: .050 seconds, answer 1402544 ok"
]
},
"execution_count": 132,
@@ -2464,7 +2464,7 @@
{
"data": {
"text/plain": [
"Puzzle 12.2: .044 seconds, answer 862486 ok"
"Puzzle 12.2: .043 seconds, answer 862486 ok"
]
},
"execution_count": 133,
@@ -2944,6 +2944,7 @@
" ax.yaxis.set_inverted(True)\n",
" plt.plot(*T(points), 'go')\n",
" plt.title(f'{t} seconds')\n",
" plt.ion()\n",
" return matplotlib.animation.FuncAnimation(fig, animate, frames=times)"
]
},
@@ -3149,42 +3150,42 @@
"</style>\n",
"\n",
"<div class=\"animation\">\n",
" <img id=\"_anim_img1e016efee37e4e37945c60fc66aa9560\">\n",
" <img id=\"_anim_img6f0cd805e6024777a7d4c6f847e74e47\">\n",
" <div class=\"anim-controls\">\n",
" <input id=\"_anim_slider1e016efee37e4e37945c60fc66aa9560\" type=\"range\" class=\"anim-slider\"\n",
" <input id=\"_anim_slider6f0cd805e6024777a7d4c6f847e74e47\" type=\"range\" class=\"anim-slider\"\n",
" name=\"points\" min=\"0\" max=\"1\" step=\"1\" value=\"0\"\n",
" oninput=\"anim1e016efee37e4e37945c60fc66aa9560.set_frame(parseInt(this.value));\">\n",
" oninput=\"anim6f0cd805e6024777a7d4c6f847e74e47.set_frame(parseInt(this.value));\">\n",
" <div class=\"anim-buttons\">\n",
" <button title=\"Decrease speed\" aria-label=\"Decrease speed\" onclick=\"anim1e016efee37e4e37945c60fc66aa9560.slower()\">\n",
" <button title=\"Decrease speed\" aria-label=\"Decrease speed\" onclick=\"anim6f0cd805e6024777a7d4c6f847e74e47.slower()\">\n",
" <i class=\"fa fa-minus\"></i></button>\n",
" <button title=\"First frame\" aria-label=\"First frame\" onclick=\"anim1e016efee37e4e37945c60fc66aa9560.first_frame()\">\n",
" <button title=\"First frame\" aria-label=\"First frame\" onclick=\"anim6f0cd805e6024777a7d4c6f847e74e47.first_frame()\">\n",
" <i class=\"fa fa-fast-backward\"></i></button>\n",
" <button title=\"Previous frame\" aria-label=\"Previous frame\" onclick=\"anim1e016efee37e4e37945c60fc66aa9560.previous_frame()\">\n",
" <button title=\"Previous frame\" aria-label=\"Previous frame\" onclick=\"anim6f0cd805e6024777a7d4c6f847e74e47.previous_frame()\">\n",
" <i class=\"fa fa-step-backward\"></i></button>\n",
" <button title=\"Play backwards\" aria-label=\"Play backwards\" onclick=\"anim1e016efee37e4e37945c60fc66aa9560.reverse_animation()\">\n",
" <button title=\"Play backwards\" aria-label=\"Play backwards\" onclick=\"anim6f0cd805e6024777a7d4c6f847e74e47.reverse_animation()\">\n",
" <i class=\"fa fa-play fa-flip-horizontal\"></i></button>\n",
" <button title=\"Pause\" aria-label=\"Pause\" onclick=\"anim1e016efee37e4e37945c60fc66aa9560.pause_animation()\">\n",
" <button title=\"Pause\" aria-label=\"Pause\" onclick=\"anim6f0cd805e6024777a7d4c6f847e74e47.pause_animation()\">\n",
" <i class=\"fa fa-pause\"></i></button>\n",
" <button title=\"Play\" aria-label=\"Play\" onclick=\"anim1e016efee37e4e37945c60fc66aa9560.play_animation()\">\n",
" <button title=\"Play\" aria-label=\"Play\" onclick=\"anim6f0cd805e6024777a7d4c6f847e74e47.play_animation()\">\n",
" <i class=\"fa fa-play\"></i></button>\n",
" <button title=\"Next frame\" aria-label=\"Next frame\" onclick=\"anim1e016efee37e4e37945c60fc66aa9560.next_frame()\">\n",
" <button title=\"Next frame\" aria-label=\"Next frame\" onclick=\"anim6f0cd805e6024777a7d4c6f847e74e47.next_frame()\">\n",
" <i class=\"fa fa-step-forward\"></i></button>\n",
" <button title=\"Last frame\" aria-label=\"Last frame\" onclick=\"anim1e016efee37e4e37945c60fc66aa9560.last_frame()\">\n",
" <button title=\"Last frame\" aria-label=\"Last frame\" onclick=\"anim6f0cd805e6024777a7d4c6f847e74e47.last_frame()\">\n",
" <i class=\"fa fa-fast-forward\"></i></button>\n",
" <button title=\"Increase speed\" aria-label=\"Increase speed\" onclick=\"anim1e016efee37e4e37945c60fc66aa9560.faster()\">\n",
" <button title=\"Increase speed\" aria-label=\"Increase speed\" onclick=\"anim6f0cd805e6024777a7d4c6f847e74e47.faster()\">\n",
" <i class=\"fa fa-plus\"></i></button>\n",
" </div>\n",
" <form title=\"Repetition mode\" aria-label=\"Repetition mode\" action=\"#n\" name=\"_anim_loop_select1e016efee37e4e37945c60fc66aa9560\"\n",
" <form title=\"Repetition mode\" aria-label=\"Repetition mode\" action=\"#n\" name=\"_anim_loop_select6f0cd805e6024777a7d4c6f847e74e47\"\n",
" class=\"anim-state\">\n",
" <input type=\"radio\" name=\"state\" value=\"once\" id=\"_anim_radio1_1e016efee37e4e37945c60fc66aa9560\"\n",
" <input type=\"radio\" name=\"state\" value=\"once\" id=\"_anim_radio1_6f0cd805e6024777a7d4c6f847e74e47\"\n",
" >\n",
" <label for=\"_anim_radio1_1e016efee37e4e37945c60fc66aa9560\">Once</label>\n",
" <input type=\"radio\" name=\"state\" value=\"loop\" id=\"_anim_radio2_1e016efee37e4e37945c60fc66aa9560\"\n",
" <label for=\"_anim_radio1_6f0cd805e6024777a7d4c6f847e74e47\">Once</label>\n",
" <input type=\"radio\" name=\"state\" value=\"loop\" id=\"_anim_radio2_6f0cd805e6024777a7d4c6f847e74e47\"\n",
" checked>\n",
" <label for=\"_anim_radio2_1e016efee37e4e37945c60fc66aa9560\">Loop</label>\n",
" <input type=\"radio\" name=\"state\" value=\"reflect\" id=\"_anim_radio3_1e016efee37e4e37945c60fc66aa9560\"\n",
" <label for=\"_anim_radio2_6f0cd805e6024777a7d4c6f847e74e47\">Loop</label>\n",
" <input type=\"radio\" name=\"state\" value=\"reflect\" id=\"_anim_radio3_6f0cd805e6024777a7d4c6f847e74e47\"\n",
" >\n",
" <label for=\"_anim_radio3_1e016efee37e4e37945c60fc66aa9560\">Reflect</label>\n",
" <label for=\"_anim_radio3_6f0cd805e6024777a7d4c6f847e74e47\">Reflect</label>\n",
" </form>\n",
" </div>\n",
"</div>\n",
@@ -3194,9 +3195,9 @@
" /* Instantiate the Animation class. */\n",
" /* The IDs given should match those used in the template above. */\n",
" (function() {\n",
" var img_id = \"_anim_img1e016efee37e4e37945c60fc66aa9560\";\n",
" var slider_id = \"_anim_slider1e016efee37e4e37945c60fc66aa9560\";\n",
" var loop_select_id = \"_anim_loop_select1e016efee37e4e37945c60fc66aa9560\";\n",
" var img_id = \"_anim_img6f0cd805e6024777a7d4c6f847e74e47\";\n",
" var slider_id = \"_anim_slider6f0cd805e6024777a7d4c6f847e74e47\";\n",
" var loop_select_id = \"_anim_loop_select6f0cd805e6024777a7d4c6f847e74e47\";\n",
" var frames = new Array(3);\n",
" \n",
" frames[0] = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90\\\n",
@@ -4933,14 +4934,14 @@
" /* set a timeout to make sure all the above elements are created before\n",
" the object is initialized. */\n",
" setTimeout(function() {\n",
" anim1e016efee37e4e37945c60fc66aa9560 = new Animation(frames, img_id, slider_id, 200.0,\n",
" anim6f0cd805e6024777a7d4c6f847e74e47 = new Animation(frames, img_id, slider_id, 200.0,\n",
" loop_select_id);\n",
" }, 0);\n",
" })()\n",
"</script>\n"
],
"text/plain": [
"<matplotlib.animation.FuncAnimation at 0x30456e5a0>"
"<matplotlib.animation.FuncAnimation at 0x137ead7f0>"
]
},
"execution_count": 160,
@@ -5173,42 +5174,42 @@
"</style>\n",
"\n",
"<div class=\"animation\">\n",
" <img id=\"_anim_img2e2d3755a0824a518eae112d3b2b646c\">\n",
" <img id=\"_anim_img9f8ef744d7ae49c1bb25688c6c5b7e4a\">\n",
" <div class=\"anim-controls\">\n",
" <input id=\"_anim_slider2e2d3755a0824a518eae112d3b2b646c\" type=\"range\" class=\"anim-slider\"\n",
" <input id=\"_anim_slider9f8ef744d7ae49c1bb25688c6c5b7e4a\" type=\"range\" class=\"anim-slider\"\n",
" name=\"points\" min=\"0\" max=\"1\" step=\"1\" value=\"0\"\n",
" oninput=\"anim2e2d3755a0824a518eae112d3b2b646c.set_frame(parseInt(this.value));\">\n",
" oninput=\"anim9f8ef744d7ae49c1bb25688c6c5b7e4a.set_frame(parseInt(this.value));\">\n",
" <div class=\"anim-buttons\">\n",
" <button title=\"Decrease speed\" aria-label=\"Decrease speed\" onclick=\"anim2e2d3755a0824a518eae112d3b2b646c.slower()\">\n",
" <button title=\"Decrease speed\" aria-label=\"Decrease speed\" onclick=\"anim9f8ef744d7ae49c1bb25688c6c5b7e4a.slower()\">\n",
" <i class=\"fa fa-minus\"></i></button>\n",
" <button title=\"First frame\" aria-label=\"First frame\" onclick=\"anim2e2d3755a0824a518eae112d3b2b646c.first_frame()\">\n",
" <button title=\"First frame\" aria-label=\"First frame\" onclick=\"anim9f8ef744d7ae49c1bb25688c6c5b7e4a.first_frame()\">\n",
" <i class=\"fa fa-fast-backward\"></i></button>\n",
" <button title=\"Previous frame\" aria-label=\"Previous frame\" onclick=\"anim2e2d3755a0824a518eae112d3b2b646c.previous_frame()\">\n",
" <button title=\"Previous frame\" aria-label=\"Previous frame\" onclick=\"anim9f8ef744d7ae49c1bb25688c6c5b7e4a.previous_frame()\">\n",
" <i class=\"fa fa-step-backward\"></i></button>\n",
" <button title=\"Play backwards\" aria-label=\"Play backwards\" onclick=\"anim2e2d3755a0824a518eae112d3b2b646c.reverse_animation()\">\n",
" <button title=\"Play backwards\" aria-label=\"Play backwards\" onclick=\"anim9f8ef744d7ae49c1bb25688c6c5b7e4a.reverse_animation()\">\n",
" <i class=\"fa fa-play fa-flip-horizontal\"></i></button>\n",
" <button title=\"Pause\" aria-label=\"Pause\" onclick=\"anim2e2d3755a0824a518eae112d3b2b646c.pause_animation()\">\n",
" <button title=\"Pause\" aria-label=\"Pause\" onclick=\"anim9f8ef744d7ae49c1bb25688c6c5b7e4a.pause_animation()\">\n",
" <i class=\"fa fa-pause\"></i></button>\n",
" <button title=\"Play\" aria-label=\"Play\" onclick=\"anim2e2d3755a0824a518eae112d3b2b646c.play_animation()\">\n",
" <button title=\"Play\" aria-label=\"Play\" onclick=\"anim9f8ef744d7ae49c1bb25688c6c5b7e4a.play_animation()\">\n",
" <i class=\"fa fa-play\"></i></button>\n",
" <button title=\"Next frame\" aria-label=\"Next frame\" onclick=\"anim2e2d3755a0824a518eae112d3b2b646c.next_frame()\">\n",
" <button title=\"Next frame\" aria-label=\"Next frame\" onclick=\"anim9f8ef744d7ae49c1bb25688c6c5b7e4a.next_frame()\">\n",
" <i class=\"fa fa-step-forward\"></i></button>\n",
" <button title=\"Last frame\" aria-label=\"Last frame\" onclick=\"anim2e2d3755a0824a518eae112d3b2b646c.last_frame()\">\n",
" <button title=\"Last frame\" aria-label=\"Last frame\" onclick=\"anim9f8ef744d7ae49c1bb25688c6c5b7e4a.last_frame()\">\n",
" <i class=\"fa fa-fast-forward\"></i></button>\n",
" <button title=\"Increase speed\" aria-label=\"Increase speed\" onclick=\"anim2e2d3755a0824a518eae112d3b2b646c.faster()\">\n",
" <button title=\"Increase speed\" aria-label=\"Increase speed\" onclick=\"anim9f8ef744d7ae49c1bb25688c6c5b7e4a.faster()\">\n",
" <i class=\"fa fa-plus\"></i></button>\n",
" </div>\n",
" <form title=\"Repetition mode\" aria-label=\"Repetition mode\" action=\"#n\" name=\"_anim_loop_select2e2d3755a0824a518eae112d3b2b646c\"\n",
" <form title=\"Repetition mode\" aria-label=\"Repetition mode\" action=\"#n\" name=\"_anim_loop_select9f8ef744d7ae49c1bb25688c6c5b7e4a\"\n",
" class=\"anim-state\">\n",
" <input type=\"radio\" name=\"state\" value=\"once\" id=\"_anim_radio1_2e2d3755a0824a518eae112d3b2b646c\"\n",
" <input type=\"radio\" name=\"state\" value=\"once\" id=\"_anim_radio1_9f8ef744d7ae49c1bb25688c6c5b7e4a\"\n",
" >\n",
" <label for=\"_anim_radio1_2e2d3755a0824a518eae112d3b2b646c\">Once</label>\n",
" <input type=\"radio\" name=\"state\" value=\"loop\" id=\"_anim_radio2_2e2d3755a0824a518eae112d3b2b646c\"\n",
" <label for=\"_anim_radio1_9f8ef744d7ae49c1bb25688c6c5b7e4a\">Once</label>\n",
" <input type=\"radio\" name=\"state\" value=\"loop\" id=\"_anim_radio2_9f8ef744d7ae49c1bb25688c6c5b7e4a\"\n",
" checked>\n",
" <label for=\"_anim_radio2_2e2d3755a0824a518eae112d3b2b646c\">Loop</label>\n",
" <input type=\"radio\" name=\"state\" value=\"reflect\" id=\"_anim_radio3_2e2d3755a0824a518eae112d3b2b646c\"\n",
" <label for=\"_anim_radio2_9f8ef744d7ae49c1bb25688c6c5b7e4a\">Loop</label>\n",
" <input type=\"radio\" name=\"state\" value=\"reflect\" id=\"_anim_radio3_9f8ef744d7ae49c1bb25688c6c5b7e4a\"\n",
" >\n",
" <label for=\"_anim_radio3_2e2d3755a0824a518eae112d3b2b646c\">Reflect</label>\n",
" <label for=\"_anim_radio3_9f8ef744d7ae49c1bb25688c6c5b7e4a\">Reflect</label>\n",
" </form>\n",
" </div>\n",
"</div>\n",
@@ -5218,9 +5219,9 @@
" /* Instantiate the Animation class. */\n",
" /* The IDs given should match those used in the template above. */\n",
" (function() {\n",
" var img_id = \"_anim_img2e2d3755a0824a518eae112d3b2b646c\";\n",
" var slider_id = \"_anim_slider2e2d3755a0824a518eae112d3b2b646c\";\n",
" var loop_select_id = \"_anim_loop_select2e2d3755a0824a518eae112d3b2b646c\";\n",
" var img_id = \"_anim_img9f8ef744d7ae49c1bb25688c6c5b7e4a\";\n",
" var slider_id = \"_anim_slider9f8ef744d7ae49c1bb25688c6c5b7e4a\";\n",
" var loop_select_id = \"_anim_loop_select9f8ef744d7ae49c1bb25688c6c5b7e4a\";\n",
" var frames = new Array(1);\n",
" \n",
" frames[0] = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90\\\n",
@@ -5609,14 +5610,14 @@
" /* set a timeout to make sure all the above elements are created before\n",
" the object is initialized. */\n",
" setTimeout(function() {\n",
" anim2e2d3755a0824a518eae112d3b2b646c = new Animation(frames, img_id, slider_id, 200.0,\n",
" anim9f8ef744d7ae49c1bb25688c6c5b7e4a = new Animation(frames, img_id, slider_id, 200.0,\n",
" loop_select_id);\n",
" }, 0);\n",
" })()\n",
"</script>\n"
],
"text/plain": [
"<matplotlib.animation.FuncAnimation at 0x304b6e300>"
"<matplotlib.animation.FuncAnimation at 0x16caad370>"
]
},
"execution_count": 163,
@@ -5650,7 +5651,7 @@
{
"data": {
"text/plain": [
"Puzzle 14.2: 1.874 seconds, answer 6876 ok"
"Puzzle 14.2: 1.802 seconds, answer 6876 ok"
]
},
"execution_count": 165,
@@ -5857,7 +5858,7 @@
{
"data": {
"text/plain": [
"Puzzle 15.1: .029 seconds, answer 1563092 ok"
"Puzzle 15.1: .028 seconds, answer 1563092 ok"
]
},
"execution_count": 173,
@@ -5879,7 +5880,7 @@
{
"data": {
"text/plain": [
"Puzzle 15.2: .042 seconds, answer 1582688 ok"
"Puzzle 15.2: .041 seconds, answer 1582688 ok"
]
},
"execution_count": 174,
@@ -6040,7 +6041,7 @@
{
"data": {
"text/plain": [
"Puzzle 16.1: .147 seconds, answer 103512 ok"
"Puzzle 16.1: .146 seconds, answer 103512 ok"
]
},
"execution_count": 182,
@@ -6104,7 +6105,7 @@
{
"data": {
"text/plain": [
"Puzzle 16.2: .854 seconds, answer 554 ok"
"Puzzle 16.2: .837 seconds, answer 554 ok"
]
},
"execution_count": 185,
@@ -6593,7 +6594,7 @@
{
"data": {
"text/plain": [
"Puzzle 18.2: .032 seconds, answer 46,18 ok"
"Puzzle 18.2: .031 seconds, answer 46,18 ok"
]
},
"execution_count": 209,
@@ -6703,7 +6704,7 @@
{
"data": {
"text/plain": [
"Puzzle 19.1: .040 seconds, answer 242 ok"
"Puzzle 19.1: .038 seconds, answer 242 ok"
]
},
"execution_count": 215,
@@ -6750,7 +6751,7 @@
{
"data": {
"text/plain": [
"Puzzle 19.2: .183 seconds, answer 595975512785325 ok"
"Puzzle 19.2: .180 seconds, answer 595975512785325 ok"
]
},
"execution_count": 218,
@@ -6919,7 +6920,7 @@
{
"data": {
"text/plain": [
"Puzzle 20.1: .028 seconds, answer 1343 ok"
"Puzzle 20.1: .029 seconds, answer 1343 ok"
]
},
"execution_count": 228,
@@ -6980,7 +6981,7 @@
{
"data": {
"text/plain": [
"Puzzle 20.2: .761 seconds, answer 982891 ok"
"Puzzle 20.2: .737 seconds, answer 982891 ok"
]
},
"execution_count": 231,
@@ -7445,7 +7446,7 @@
{
"data": {
"text/plain": [
"Puzzle 22.1: .318 seconds, answer 14273043166 ok"
"Puzzle 22.1: .313 seconds, answer 14273043166 ok"
]
},
"execution_count": 259,
@@ -7538,7 +7539,7 @@
{
"data": {
"text/plain": [
"Puzzle 22.2: 1.136 seconds, answer 1667 ok"
"Puzzle 22.2: 1.108 seconds, answer 1667 ok"
]
},
"execution_count": 262,
@@ -7602,46 +7603,17 @@
"name": "stdout",
"output_type": "stream",
"text": [
"271 monkeys (16%) bought, total price 1667, mean 6.2\n"
"271 monkeys (16%) bought, total price 1667, mean 6.2,\n",
"Histogram of prices: {3: 43, 4: 34, 5: 33, 6: 32, 7: 37, 8: 42, 9: 50}\n"
]
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"Counter({9: 50, 3: 43, 8: 42, 7: 37, 4: 34, 5: 33, 6: 32})"
]
},
"execution_count": 266,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"prices = [p for secret in secrets for d, p in price_timeline(secret).items() if d == best_deltas]\n",
"hist = {i: prices.count(i) for i in range(10) if i in prices}\n",
"print(f'{len(prices)} monkeys ({len(prices)/len(secrets):.0%}) bought, '\n",
" f'total price {sum(prices)}, mean {mean(prices):3.1f}')\n",
"plt.hist(prices, rwidth=0.9, bins=[x+0.5 for x in range(10)]); plt.show()\n",
"Counter(prices)"
" f'total price {sum(prices)}, mean {mean(prices):3.1f},\\n'\n",
" f'Histogram of prices: {hist}')"
]
},
{
@@ -7718,7 +7690,7 @@
"id": "58c39447-f458-4254-bb4c-144effd3f23c",
"metadata": {},
"source": [
"I waas also curious about exactly how many possible *n*-tuples of deltas there are for any sequence of *n* digits (not just from the secrets):"
"I was also curious about exactly how many possible *n*-tuples of deltas there are for any sequence of *n* digits (not just from the secrets):"
]
},
{
@@ -7781,17 +7753,44 @@
},
{
"cell_type": "markdown",
"id": "bf3f03a4-c9ea-4429-82a4-3f54b7846ce0",
"id": "068355da-13fb-4076-a7ce-29fccf83bb14",
"metadata": {},
"source": [
"With 2 digits there are 2<sup>4</sup> sequences of length 4 that make (2<sup>4</sup> - 1) unique delta 3-tuples, because the sequence (0, 0, 0, 0) and (1, 1, 1, 1) both yield the deltas (0, 0, 0). \n",
"\n",
"Now we try with 10 digits, for tuples of length 1 to 5:"
"With 2 digits there are 2<sup>4</sup> sequences of length 4 that make (2<sup>4</sup> - 1) unique delta 3-tuples, because the sequence (0, 0, 0, 0) and (1, 1, 1, 1) both yield the deltas (0, 0, 0). The pattern holds for other lengths with two digits:"
]
},
{
"cell_type": "code",
"execution_count": 276,
"id": "9dac4989-6fc8-4b45-87de-6dcfca7a91c9",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{2: 7, 3: 15, 4: 31, 5: 63, 6: 127, 7: 255, 8: 511, 9: 1023}"
]
},
"execution_count": 276,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"{n: len(all_deltas(digits=range(2), n=n)) for n in range(2, 10)}"
]
},
{
"cell_type": "markdown",
"id": "73a92c4f-06e8-4266-a6ef-68074dc0b8ce",
"metadata": {},
"source": [
"Now we try with 10 digits, for tuples of length 1 to 5:"
]
},
{
"cell_type": "code",
"execution_count": 278,
"id": "2bb368b8-d5e7-431c-bd2c-19aa41983b8d",
"metadata": {},
"outputs": [
@@ -7801,7 +7800,7 @@
"{1: 19, 2: 271, 3: 3439, 4: 40951, 5: 468559}"
]
},
"execution_count": 276,
"execution_count": 278,
"metadata": {},
"output_type": "execute_result"
}
@@ -7815,7 +7814,7 @@
"id": "47add4c5-499a-4c6f-a148-74093a72e3c7",
"metadata": {},
"source": [
"This sequence of integers, 19, 271, 3439, 40951, 468559 [**appears**](https://oeis.org/search?q=+1%2C+19%2C+271%2C+3439%2C+40951&language=english&go=Search) in the Online Encyclopedia of Integer Sequences (OEIS), but it is not described as having anything to do with deltas, but rather as 10<sup>*n*</sup> - 9<sup>*n*</sup>."
"This sequence of integers, 19, 271, 3439, 40951, 468559 [**appears**](https://oeis.org/search?q=+1%2C+19%2C+271%2C+3439%2C+40951&language=english&go=Search) in the Online Encyclopedia of Integer Sequences (OEIS), a great resource for looking up a sequence of integers. It is not described as having anything to do with deltas, but rather as 10<sup>*n*</sup> - 9<sup>*n*</sup>."
]
},
{
@@ -7830,7 +7829,7 @@
},
{
"cell_type": "code",
"execution_count": 279,
"execution_count": 281,
"id": "85f5b145-8c5e-448c-8b45-ad5750252ff2",
"metadata": {},
"outputs": [
@@ -7881,7 +7880,7 @@
},
{
"cell_type": "code",
"execution_count": 281,
"execution_count": 283,
"id": "289d2325-1e58-41f5-b4b2-b90ae26e7887",
"metadata": {},
"outputs": [],
@@ -7906,7 +7905,7 @@
},
{
"cell_type": "code",
"execution_count": 282,
"execution_count": 284,
"id": "6425577d-4ca9-45de-9698-cd9b026f7ce6",
"metadata": {},
"outputs": [
@@ -7916,7 +7915,7 @@
"Puzzle 23.1: .001 seconds, answer 1170 ok"
]
},
"execution_count": 282,
"execution_count": 284,
"metadata": {},
"output_type": "execute_result"
}
@@ -7942,7 +7941,7 @@
},
{
"cell_type": "code",
"execution_count": 284,
"execution_count": 286,
"id": "c497adf7-caee-4ced-9d62-0a589879b460",
"metadata": {},
"outputs": [],
@@ -7964,17 +7963,17 @@
},
{
"cell_type": "code",
"execution_count": 285,
"execution_count": 287,
"id": "0b5f08ac-18e2-4933-9737-cdbc842c5809",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Puzzle 23.2: .004 seconds, answer bo,dd,eq,ik,lo,lu,ph,ro,rr,rw,uo,wx,yg ok"
"Puzzle 23.2: .003 seconds, answer bo,dd,eq,ik,lo,lu,ph,ro,rr,rw,uo,wx,yg ok"
]
},
"execution_count": 285,
"execution_count": 287,
"metadata": {},
"output_type": "execute_result"
}
@@ -8024,7 +8023,7 @@
},
{
"cell_type": "code",
"execution_count": 289,
"execution_count": 291,
"id": "47421581-71df-4c72-a62e-c40d0596fdbb",
"metadata": {},
"outputs": [
@@ -8075,7 +8074,7 @@
},
{
"cell_type": "code",
"execution_count": 291,
"execution_count": 293,
"id": "43b29260-d912-4cfc-91ce-d303ec1c86df",
"metadata": {},
"outputs": [],
@@ -8104,7 +8103,7 @@
},
{
"cell_type": "code",
"execution_count": 293,
"execution_count": 295,
"id": "a9a4780f-6033-452f-b49c-74b97c9e2440",
"metadata": {},
"outputs": [],
@@ -8126,7 +8125,7 @@
},
{
"cell_type": "code",
"execution_count": 294,
"execution_count": 296,
"id": "72437439-dddf-4202-9944-36e796800304",
"metadata": {},
"outputs": [
@@ -8136,7 +8135,7 @@
"Puzzle 24.1: .001 seconds, answer 36035961805936 ok"
]
},
"execution_count": 294,
"execution_count": 296,
"metadata": {},
"output_type": "execute_result"
}
@@ -8189,7 +8188,7 @@
},
{
"cell_type": "code",
"execution_count": 298,
"execution_count": 300,
"id": "9021ad30-f505-4164-9feb-5af740632182",
"metadata": {},
"outputs": [
@@ -8244,7 +8243,7 @@
" 'z00': ('x00', 'XOR', 'y00')}"
]
},
"execution_count": 298,
"execution_count": 300,
"metadata": {},
"output_type": "execute_result"
}
@@ -8276,17 +8275,17 @@
},
{
"cell_type": "code",
"execution_count": 300,
"execution_count": 302,
"id": "b35c397d-6b68-4ba6-bb46-806a449f1398",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Counter({'XOR': 89, 'AND': 89, 'OR': 44})"
"Counter({'AND': 89, 'XOR': 89, 'OR': 44})"
]
},
"execution_count": 300,
"execution_count": 302,
"metadata": {},
"output_type": "execute_result"
}
@@ -8317,7 +8316,7 @@
},
{
"cell_type": "code",
"execution_count": 303,
"execution_count": 305,
"id": "ec8d86d4-8caf-40f2-b516-c7da4acbda19",
"metadata": {},
"outputs": [],
@@ -8371,7 +8370,7 @@
},
{
"cell_type": "code",
"execution_count": 305,
"execution_count": 307,
"id": "1f259a97-dbad-40dc-903d-6436a77e1903",
"metadata": {},
"outputs": [],
@@ -8383,13 +8382,13 @@
" Swap wires accordingly, and yield each swapped wire.\n",
" If `verbose` is true, print debugging information.\"\"\"\n",
" \n",
" def out(a_gate: Tuple[str, str, str]): \n",
" def out(a_gate: Tuple[str, str, str]) -> Wire: \n",
" \"\"\"The name of the output wire for this gate.\"\"\"\n",
" return device.outputs[gate(*a_gate)]\n",
" return device.outputs[*a_gate]\n",
"\n",
" def swap(a: str, b: str, debug_msg: str) -> Tuple[str]:\n",
" def swap(a: Wire, b: Wire, debug_msg: str) -> Tuple[str]:\n",
" \"\"\"Swap wires `a` and `b` in device.\"\"\"\n",
" if verbose: print(f'swapping ({a}, {b}) because {debug_msg}')\n",
" if verbose: print(f'swap ({a}, {b}) because {debug_msg}')\n",
" device[a], device[b] = device[b], device[a]\n",
" device.compute_outputs() # Recompute outputs after this swap\n",
" return a, b\n",
@@ -8406,7 +8405,7 @@
" if XOR2 == XORz:\n",
" pass # Keep calm and carry on\n",
" elif XOR2 in device.outputs:\n",
" yield from swap(out(XOR2), z, f'XOR2_{i} is {XOR2} -> {out(XOR2)}, but should output directly to {z}.')\n",
" yield from swap(out(XOR2), z, f'XOR2_{i} -> {out(XOR2)}, but should -> {z}.')\n",
" else: # There is a discrepancy; find the 2 wires not shared between XOR2 and XORz\n",
" counts = Counter(XOR2 + XORz)\n",
" a, b = [wire for wire in counts if counts[wire] == 1] # Assumes there will be 2 such wires\n",
@@ -8418,7 +8417,7 @@
},
{
"cell_type": "code",
"execution_count": 306,
"execution_count": 308,
"id": "e9b87c38-f67c-4948-9af6-251021747e9d",
"metadata": {},
"outputs": [
@@ -8428,7 +8427,7 @@
"Puzzle 24.2: .000 seconds, answer jqf,mdd,skh,wpd,wts,z11,z19,z37 ok"
]
},
"execution_count": 306,
"execution_count": 308,
"metadata": {},
"output_type": "execute_result"
}
@@ -8443,12 +8442,14 @@
"id": "b4741dac-4221-4770-bc53-4bb92da229ea",
"metadata": {},
"source": [
"### Part 3: Debugging and Reflections\n",
"\n",
"Here I show the debugging output turned on:"
]
},
{
"cell_type": "code",
"execution_count": 308,
"execution_count": 310,
"id": "dafe10de-c35e-4b01-9517-f048670002b3",
"metadata": {},
"outputs": [
@@ -8456,10 +8457,10 @@
"name": "stdout",
"output_type": "stream",
"text": [
"swapping (wpd, z11) because XOR2_11 is ('gkc', 'XOR', 'qqw') -> wpd, but should output directly to z11.\n",
"swapping (jqf, skh) because XOR2_15 is ('jqf', 'XOR', 'rkt'), but z15 expects ('rkt', 'XOR', 'skh').\n",
"swapping (mdd, z19) because XOR2_19 is ('cmp', 'XOR', 'wfc') -> mdd, but should output directly to z19.\n",
"swapping (wts, z37) because XOR2_37 is ('smt', 'XOR', 'wpp') -> wts, but should output directly to z37.\n"
"swap (wpd, z11) because XOR2_11 -> wpd, but should -> z11.\n",
"swap (jqf, skh) because XOR2_15 is ('jqf', 'XOR', 'rkt'), but z15 expects ('rkt', 'XOR', 'skh').\n",
"swap (mdd, z19) because XOR2_19 -> mdd, but should -> z19.\n",
"swap (wts, z37) because XOR2_37 -> wts, but should -> z37.\n"
]
},
{
@@ -8468,7 +8469,7 @@
"['wpd', 'z11', 'jqf', 'skh', 'mdd', 'z19', 'wts', 'z37']"
]
},
"execution_count": 308,
"execution_count": 310,
"metadata": {},
"output_type": "execute_result"
}
@@ -8477,6 +8478,14 @@
"list(find_swaps(Device(connections), verbose=True))"
]
},
{
"cell_type": "markdown",
"id": "a9f0deaa-6695-4dec-ac17-fbceb8958483",
"metadata": {},
"source": [
"I got the correct answer, but it was disapointing because it felt like my strategy was \"hack on it until it works on my one input, with no guarantee that it will work on any other input.\""
]
},
{
"cell_type": "markdown",
"id": "b8d3967e-3473-47b0-b1b8-687c56e49138",
@@ -8491,7 +8500,7 @@
},
{
"cell_type": "code",
"execution_count": 310,
"execution_count": 313,
"id": "f5971853-7139-4f17-bdc5-6c51e12a928d",
"metadata": {},
"outputs": [
@@ -8559,7 +8568,7 @@
},
{
"cell_type": "code",
"execution_count": 312,
"execution_count": 315,
"id": "5302ac58-91fc-475a-83d9-cea91457df3b",
"metadata": {},
"outputs": [],
@@ -8581,17 +8590,17 @@
},
{
"cell_type": "code",
"execution_count": 313,
"execution_count": 316,
"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": 313,
"execution_count": 316,
"metadata": {},
"output_type": "execute_result"
}
@@ -8622,12 +8631,12 @@
"\n",
"Here are all the puzzle answers and timings. I got all the puzzles correct! And I did it before midnight (my time) on December 25th, a rarity for me. \n",
"\n",
"The median run time is about 5 milliseconds, with 3 puzzles taking over a second, but none taking 2 seconds (barely!). I didn't count the time that `parse` takes, but that is less than a millisecond per day. Some people in the Rust subreddit were talking about completing the puzzles in less than 10 seconds of run time. I managed to do that, even with Python's slow interpreter rather than [Rust](https://www.rust-lang.org/)'s fast compiler. But others were talking about doing all 10 years of puzzles in less than 10 seconds, and I can't compete with that."
"The median run time is about 5 milliseconds, with 3 puzzles taking over a second, but none taking 2 seconds (barely!). I didn't count the time that `parse` takes, but that is less than a millisecond per day. Some people in the Rust subreddit were talking about completing the puzzles in less than 10 seconds of run time. I managed to do that, even with Python's slow interpreter rather than [Rust](https://www.rust-lang.org/)'s fast compiler. But others were talking about doing all *10 years* of puzzles in less than 10 seconds, and I can't compete with that."
]
},
{
"cell_type": "code",
"execution_count": 316,
"execution_count": 319,
"id": "34813fc9-a000-4cd8-88ae-692851b3242c",
"metadata": {},
"outputs": [
@@ -8641,53 +8650,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: .022 seconds, answer 2401 ok\n",
"Puzzle 4.1: .021 seconds, answer 2401 ok\n",
"Puzzle 4.2: .015 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: .001 seconds, answer 5329 ok\n",
"Puzzle 6.2: 1.967 seconds, answer 2162 ok\n",
"Puzzle 6.2: 1.932 seconds, answer 2162 ok\n",
"Puzzle 7.1: .014 seconds, answer 1985268524462 ok\n",
"Puzzle 7.2: .595 seconds, answer 150077710195188 ok\n",
"Puzzle 8.1: .003 seconds, answer 220 ok\n",
"Puzzle 7.2: .586 seconds, answer 150077710195188 ok\n",
"Puzzle 8.1: .002 seconds, answer 220 ok\n",
"Puzzle 8.2: .003 seconds, answer 813 ok\n",
"Puzzle 9.1: .020 seconds, answer 6332189866718 ok\n",
"Puzzle 9.1: .019 seconds, answer 6332189866718 ok\n",
"Puzzle 9.2: .021 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: .060 seconds, answer 232454623677743 ok\n",
"Puzzle 12.1: .051 seconds, answer 1402544 ok\n",
"Puzzle 12.2: .044 seconds, answer 862486 ok\n",
"Puzzle 11.2: .059 seconds, answer 232454623677743 ok\n",
"Puzzle 12.1: .050 seconds, answer 1402544 ok\n",
"Puzzle 12.2: .043 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.874 seconds, answer 6876 ok\n",
"Puzzle 15.1: .029 seconds, answer 1563092 ok\n",
"Puzzle 15.2: .042 seconds, answer 1582688 ok\n",
"Puzzle 16.1: .147 seconds, answer 103512 ok\n",
"Puzzle 16.2: .854 seconds, answer 554 ok\n",
"Puzzle 14.2: 1.802 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: .146 seconds, answer 103512 ok\n",
"Puzzle 16.2: .837 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: .004 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 18.2: .031 seconds, answer 46,18 ok\n",
"Puzzle 19.1: .004 seconds, answer 242 ok\n",
"Puzzle 19.2: .183 seconds, answer 595975512785325 ok\n",
"Puzzle 19.2: .180 seconds, answer 595975512785325 ok\n",
"Puzzle 20.1: .022 seconds, answer 1343 ok\n",
"Puzzle 20.2: .761 seconds, answer 982891 ok\n",
"Puzzle 20.2: .737 seconds, answer 982891 ok\n",
"Puzzle 21.1: .000 seconds, answer 205160 ok\n",
"Puzzle 21.2: .004 seconds, answer 252473394928452 ok\n",
"Puzzle 22.1: .318 seconds, answer 14273043166 ok\n",
"Puzzle 22.2: 1.136 seconds, answer 1667 ok\n",
"Puzzle 22.1: .313 seconds, answer 14273043166 ok\n",
"Puzzle 22.2: 1.108 seconds, answer 1667 ok\n",
"Puzzle 23.1: .001 seconds, answer 1170 ok\n",
"Puzzle 23.2: .004 seconds, answer bo,dd,eq,ik,lo,lu,ph,ro,rr,rw,uo,wx,yg 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.005 median, 0.169 mean, 8.284 total.\n"
"Time in seconds: 0.005 median, 0.165 mean, 8.084 total.\n"
]
}
],