AoC
This commit is contained in:
1 parent
e31786e7e4
commit
778f22dbde
2 files changed
+477
-195
No files matched your search
+294
-82
@@ -329,7 +329,7 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0.001 seconds for correct answer: 8,401\n"
|
||||
"0.000 seconds for correct answer: 8,401\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -350,7 +350,7 @@
|
||||
"source": [
|
||||
"#### Part 2: Find the item type that corresponds to the badges of each three-Elf group. What is the sum of the priorities of those item types?\n",
|
||||
"\n",
|
||||
"My utility function `batched(in3, 3)` (from the [itertools recipes](https://docs.python.org/3/library/itertools.html#itertools-recipes) groups a sequence into subsequences of length 3; then we find the intersection and get its priority:"
|
||||
"My utility function `batched(in3, 3)` groups a sequence into subsequences of length 3; then we find the intersection and get its priority:"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -920,7 +920,7 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0.055 seconds for correct answer: 291,840\n"
|
||||
"0.057 seconds for correct answer: 291,840\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -961,7 +961,7 @@
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 864x864 with 1 Axes>"
|
||||
]
|
||||
@@ -973,9 +973,8 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"square_plot([max(in8, key=lambda p: scenic_score(p, in8))], 'ro',\n",
|
||||
" extra=lambda: plt.scatter(*T(in8), c=list(in8.values()), \n",
|
||||
" cmap=plt.get_cmap('YlGn')))"
|
||||
"naked_plot([max(in8, key=lambda p: scenic_score(p, in8))], 'ro', size=12)\n",
|
||||
"plt.scatter(*T(in8), c=list(in8.values()), cmap=plt.get_cmap('YlGn'));"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1091,8 +1090,8 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0.023 seconds for correct answer: 6,236\n",
|
||||
"0.108 seconds for correct answer: 2,449\n"
|
||||
"0.024 seconds for correct answer: 6,236\n",
|
||||
"0.112 seconds for correct answer: 2,449\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -1130,9 +1129,9 @@
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 864x864 with 1 Axes>"
|
||||
"<Figure size 720x720 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
@@ -1142,7 +1141,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"square_plot(move_rope(in9, knots=2), '.');"
|
||||
"naked_plot(move_rope(in9, knots=2), '.'); "
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1152,9 +1151,9 @@
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 864x864 with 1 Axes>"
|
||||
"<Figure size 720x720 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
@@ -1164,7 +1163,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"square_plot(move_rope(in9, knots=10), '.');"
|
||||
"naked_plot(move_rope(in9, knots=10), '.');"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1174,9 +1173,9 @@
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 864x864 with 1 Axes>"
|
||||
"<Figure size 720x720 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
@@ -1186,7 +1185,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"square_plot(move_rope(in9, knots=20), '.');"
|
||||
"naked_plot(move_rope(in9, knots=20), '.');"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1196,9 +1195,9 @@
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 864x864 with 1 Axes>"
|
||||
"<Figure size 720x720 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
@@ -1208,7 +1207,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"square_plot(move_rope(in9, knots=100), '.');"
|
||||
"naked_plot(move_rope(in9, knots=100), '.');"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1291,15 +1290,13 @@
|
||||
" Remember that an `addx` instruction takes 2 cycles.\"\"\"\n",
|
||||
" X = 1\n",
|
||||
" cycle = 0\n",
|
||||
" results = []\n",
|
||||
" for (op, *args) in program:\n",
|
||||
" cycle += 1\n",
|
||||
" results.append((cycle, X))\n",
|
||||
" yield (cycle, X)\n",
|
||||
" if op == 'addx':\n",
|
||||
" cycle += 1\n",
|
||||
" results.append((cycle, X))\n",
|
||||
" yield (cycle, X)\n",
|
||||
" X += args[0]\n",
|
||||
" return results\n",
|
||||
"\n",
|
||||
"answer(10.1, 12560, lambda: sum(c * X for c, X in run(in10) if c in range(20, 221, 40)))"
|
||||
]
|
||||
@@ -1324,14 +1321,14 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0.012 seconds for correct answer: PLPAFBCL\n"
|
||||
"0.036 seconds for correct answer: PLPAFBCL\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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M2cKzU/v/JxXdjvGbsdM3m3n2SfvttPk3dy3Y+x2Z84Umj/f+Tmv7HaM3Y6ZvNvOs0/ebafJu7lvx9jtzpwpNJ/W69dCvPVy+Zz/zG7H2O2YybvtPPvk3XaavJv7dozd7sxpQvPyhbZf11o/1lq/Lr/6Aty/Ybdj7HbM5N12nn3ybjtN3s19O8Zu9+c0/+scAID7cpq/0QQA4L4ITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAxIfdB3jr87fvX9brD6//tF5/5NOTb5T6967Z7drNdz9/DfftmMm7uW/z7Pwz5pHf2aPuNvm+nXX303zD9stAf621Pr75+GX5rvz/1TW7Xbv57uev4b4dM3k3922enX/GPPI7e9TdJt+3M+9+pn86f16/D7Quv3/ecJZJrtnt2s13P38N9+2Yybu5b/Ps/DPmkd/Zo+42+b6ddvczheand37Oq2t2u3bz3c9fw307ZvJu7ts8O/+MeeR39qi7Tb5vp939TKH5852f8+qa3a7dfPfz13Dfjpm8m/s2z84/Yx75nT3qbpPv22l3P1NoPq3Xryd46+XyOf/ZNbtdu/nu56/hvh0zeTf3bZ6df8Y88jt71N0m37fT7n6a0Lx8serXtdaPtdavy6/bv4j17K7Z7drNdz9/DfftmMm7uW/z7Pwz5pHf2aPuNvm+nXn30/yvcwAA7stp/kYTAID7IjQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNAEACAhNAEASAhNAAASQhMAgITQBAAgITQBAEgITQAAEkITAICE0AQAICE0AQBICE0AABJCEwCAhNALine truncated
|
||||
"image/png": "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\n",
|
||||
"text/plain": [
|
||||
"<Figure size 864x864 with 1 Axes>"
|
||||
"<Figure size 576x72 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
@@ -1349,7 +1346,7 @@
|
||||
" x, y = (cycle - 1) % 40, (cycle - 1) // 40\n",
|
||||
" if abs(X - x) <= 1:\n",
|
||||
" points.append((x, y))\n",
|
||||
" square_plot(points)\n",
|
||||
" naked_plot(points, size=(8, 1))\n",
|
||||
" \n",
|
||||
"answer(10.2, \"PLPAFBCL\", lambda: render(in10) or \"PLPAFBCL\")"
|
||||
]
|
||||
@@ -1491,7 +1488,7 @@
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0.001 seconds for correct answer: 54,036\n",
|
||||
"0.282 seconds for correct answer: 13,237,873,355\n"
|
||||
"0.278 seconds for correct answer: 13,237,873,355\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -1593,7 +1590,7 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0.036 seconds for correct answer: 394\n"
|
||||
"0.039 seconds for correct answer: 394\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -1662,7 +1659,7 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0.039 seconds for correct answer: 388\n"
|
||||
"0.038 seconds for correct answer: 388\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -1706,9 +1703,9 @@
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAqsAAAFUCAYAAAADN3WgAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOydeZgcVdX/P/fWdCpAWIOIjCjh1SIuGDSAoqBWUFRA3EEQMYLgBm/EDfUNLj9RXpQXiKAIKruioICKKAhpFFC2IGENzeJgGCCQISSZraanqn5/nNOZ6uqq7mEmk+mBOs8zD2S+U+unzq17q879lonjmCKKKKKIIooooogiimjHsJO9A0UUUUQRRRRRRBFFFJEXRWe1iCKKKKKIIoooooi2jaKzWkQRRRRRRBFFFFFE20bRWS2iiCKKKKKIIoooom2j6KwWUUQRRRRRRBFFFNG2UXRWiyiiiCKKKKKIIopo2yg6q0UUUUQRRRRRRBFFtG0UndUiiiiiiCKKKKKIIto2is5qEUUUUUQRRRRRRBFtG0VntYgiiiiiiCKKKKKIto2is1pEEUUUUUQRRRRRRNtG0VktoogiiiiiiCKKKKJto+isFlFEEUUUUUQRRRTRtlF0VosooogiiiiiiCKKaNsoOqtFFFFEEUUUUUQRRbRtFJ3VIooooogiiiiiiCLaNorOahFFFFFEEUUUUUQRbRtFZ7WIIooooogiiiiiiLaNorNaRBFFFFFEEUUUUUTbRsdk70BeRHFlW+Bw4BXAjcDF1ngDNb0aLdle9ZcBZeDSkp0b1PQgLO+o+rbA1cAVruNXE/pOwCeBmcCVwJWu44cJfWfgE8AM4Argatfx44S+K3AoMA24FLg+pb8ZOFj/ebHr+P9IaAZ4O/ARYAi4yHX82xO6BfYB3g/0Aue7jn93QneA/fWnBzjXdfwHEueupMu+C3gSOMca75GE7uq2feA/qi9P6Bvpvu8JPKT6kwl9hh777sB9wHnWeCsT+hZ67nYB7gTOt8Z7NqFvDcwHXg3cClxkjdeb0JuyD8JyA3vX8UfNPoorDeyt8cKE3sDeGi9O6A3sU3ode2u8fyS0BvbWeLcn9Ab21nh3J/QG9tZ4Lxj2UVxpYG+NFyT0BvbWeC+IvA/CcgN71/EfSegN7F3HX57QG9i7jv9kQm9g7zr+yoTewN51/GcTegN71/F7E3oDe9fx11veF+wL9kwC+6ne5rdLmDiOW//VBo4oruwGXAeUgOkIwKeA3azxnqlGS96OXHAdgKt6F/Dmkp27NgjL+wO/UX2a6vcAvuv4g0FYPgT4ueol1W8G3uM6/nAQlj8L/J8u66h+NXCg6/hREJa/DizUfTNAP/Br4EjX8eMgLP8Q+JzqAIPAj13H/6o2Wj8DPgpsDMSqn+A6/onaaF2KXHibACFygX/Jdfwzg7DcAfwZeBOSWFVgGPiU6/i/iuLKdCSZX6v6kOoHWeNdGcWVTYF/ADuoHqi+vzXe9VFcmYk0Ji/W7Q+qPs8a77YormwH3AZsrvqAbuMt1nj3amfhFj22jfXc9ANvtMZ7JIorr0EaIxfYCOgDVgO7WuM90Yp9EJZz2buO35J9FFdy2VvjDUdxJZe9NV4UxZVc9tZ4cRRXMtlb431VG61M9tZ4J2qjlcneGu/MKK7ksrfGm8rsd7PGe7wJ+92t8XqiuJLL3hpvbRRXctlb4401768BPjKOvP+J6/hfmei8D8JyLnvX8a8MwnIue9fxrw/Cci571/FvC8JyLnvX8e/VzkIme9fxHwnCci571/EfD8JyLnvX8XvGm/cbgP0PgM+Pg/0lwLsL9s8v9qNs8zPZt0ObTxtFu3ZWlwE7pX49BJwZxmu/CCwHtkvpg8CJUbzmRORC3yKl9wPHAeeqvnFK7wM+jXRMljNy4dWiF7ng7gGWZeh9yI1mNSOJm4wBYDdgS+AvyIWR3v+dgNcBFyMXVlp/KfAe4KcZy/cD25Rs5+HA/2Zs/1lgG+AbwNcy9v9xYHvgVOAzSOImY5k13quiuHIhch6ST+Vj4BZrvD2iuHIVch6SJSYhcI013r5RXPkn8EYk6WsxDPzaGu/jUVy5H5id2vYQcGY16m7KXn9y2Zds53jZ3w08kKGPlv0Wuo089jsjjWAe+3cDZ2Us34+w/SRwUsb2a+y/rj957E8BPksbsgfGxb4adRfsx8jedfxXBWE5l73r+HsEYTmXvev4+wZhOZe96/gfD8LyhLFn/G1+wb5g34z9rUgnPBkDwO4l27k5Y2e/vW5j0tp82ijargxAXwO+PEOahjzK/ikywkvHdOTiuobsWtyNgUOQx9zVDH0T5FF4qHoa7gzd/vZAlLP+9yOP6UsZegfwXuQ1RPrCRte5LyMjqHRUgXcix5i+cGv6XnoM6QsX5JzMBQ6i8dhAzqkHfJjGCxdgB2VzAI3XjQF209cJ76Tx/DvAO1XfjfpGC13fAbr+HTK23e7sN2LDsD+Y5uwPoTn7j9Kc/Uco2Bfs62MHfUWby15fIeeyVz2Xva5/h4xtF+wL9lOBfVY/qgN5bT+TbDajYf8OJrnNb6dygHacYDVE/n4N6k+ePtBC71c9nTggI8U+1bMeN0cJPeviDRPrD3P0Af3JWj5SrT9HjxN61v6ZxPqzwjJyfsaqD+lPVkSMJH5WVFXPOjaQ1xNTlX1Ewb5gX7DPioJ9wf6Fzj5Lnyrs2ybarrNqjfcM8E/kNUEy+oGzSnZuF1ChEXAf8tpgKbCSRsB9yCjtRiRJ0tGP1JZcTfbFPQicB/ye7PNWBX6F1J3lxaXAL8lObqvrPpf8C+ga3cf+DC0AbkKOsS+lxcDTwF3IOUrrEVCxxnsUODtj/cPAP5TNORn7N4RMUhpCzkH6/AbAr1S/ksYkGESKup9B6msy2buO38XEs8+KdmGfxQZG2GexTbL/SYaeZH9Wxvrbgr01XhcF+wlh7zp+U/au4zdl7zp+U/aq57LX9U/1vM+rpyvYv3DZ/5bm7P9APnvD+NivZP20+W0TbddZ1fgY8CiwFjnR/UgB9qmqfwh4IqEPIDP4ztEZeu9FYK1hZHR0PvA71/GHgf2AVar3qv4j1/Gv1RmIB+jvk/p3XMe/zXX8VcCBuk9rE/oXXMd/wHX8bmRW4oDqa/X/P+k6/uM6g/MLukyv6v3I5K1nXce/DfhOQq/twwGu4w+4jv9X4Ecp/VlgPz223+qxDuqxr9Fz8V6dsX6OnqsB1dfqufyQnttT9Fz3J/RHkZmQAN9GBhN9+tMLPAgcpfoXkSTpTfzNXfp79O8eTLDr0/V9R/VDmSD21ni57K3xrtVZ5+8jg7013m3WeLnsrfEesMbLZW+N97jO4Mxkb433rBa0Z7K3xhuwxruWHPZ6bL+jOftzac7+VKYoez2+8eZ9JvtJzvv3ad7nstdjy2N/gObF85b9emrzn8/sW7X5BfuJYd/dos1ftQHa/PGyb5toywlWsM7O4QhkltsfFdq6qEZLOpAC6VcCvy3ZuTcm9SAsTwOORmpOLnIdf0lK3whYALwIsQG5J6VvilxkmwNnuo7/cErfSpefDpzhJmxAVH8x8N/6zx+5jr8ipb8MmUE4CJymSZHU/wspfF6t+tqU/lqkuPppYJGbsPkAiOLKXOSCWw6cnrTvUX1PpD71QeTJ1XBKfwfSCNwD/MIaL0rp70Vqam5HrDiS1k1G170nMrL9bYZ+KLArcK013h9T627KXmfHrmPvOv5zYq/1k+vYW+Pdk9Lr2FvjPZzS69gnbUBUr2Nvjbcipdex105wUq9jb423NqXXsU9aO6n+vGWvs2PXsbfGuzGl17G3xntB5X0QluvYuwn7HtXr2OvNPKnXsXcdP0rpdezdevueBvYZ+jr2ruP/MbXuOvbaSUvq48r7gn3BnkliP9Xb/HaItuysamfgKuTCHUbsKi4APmuNF1WjJdsij8h3TOinA8eV7Nw4CMs7qP4SpF7ERWxCvgcQhOXZyOP/LZFH4tOAr7qOf4bqr0fsImpF8R3AZ13Hv0D1tyCP8DuQR+4dwMddx79c9X0QO4paOUGM2GD8VfUPABfqvhv97wGu49+k+mHI4/2a3o/YbPxL9aOBHzBS77MKeJfr+Mv0/P0PYrURIIXuTwDvtMZ7VDsLP0ASO9B9fwTYxxrvSe0snAkcpnoJmRG5rzXeM9pZuAD4gOrTEBuQA6zxetVK41Jgb92/acjI7SPWeIPq0/kHpLB8SNlcDhym1lFN2WtBfiZ7V2xEmrKP4kome2u8M1TPZG+Nd4Hqmeyt8S5XPZO9Nd5fVc9kb413k+qZ7K3x/qV6JntrvOc9e52ElWZ/hvKLo7iSyd4abzLz/kDX8a9RfULzPgjLWez3cR2/SzsLmexdx39SOwuZ7F3Hf0Y7C5nsXcfvVfukTPau2AflsnfFPiiXvSv2QbnsR5P3BfuC/WSxn6Q2fx9rvK7xtvm0UbRrZ/WPiElucpZaP/Bla7wzq9GSGxErjOQsvD7gU1G85jfIyZ6NgEvqH0Yu6i7EEiRZm9qPjBqXILYOM1O7VbMheVT1TTP0V+l6usi2ytgBmfl3H42zQ9cg9hyzyLbCWKn6bsBfU+uPkRHVrJLtfBfScCRnEIbA/dZ4O0dx5WCkViepDwM3W+PtFcWVzwE/TK1/CLEfem8UVxYiVhhJPUDsh+ZHceVUZASc3P8B4KfWeF+M4sr5iCOBm9D7ge9b432vFfsgLOeyR7z2ctmXbOc1wL+R0fdEsO/Tv8ljvwlwPxPEHrE5ed6yj+LKmNlXo+7JYt+PuJvksV+L3GTz2PeoPmb2ruPvHITlXPau4+8VhOVc9q7jvzcIy7nsXcefH4TlUxDLuwb2ruN/MQjL5yEzkxvYu47/vSAs57J3xWt0zOyRNn+87LuBzTL0Gvsusu2F1gf7XYFryWe/D1L+lcf+o4jPaB77zwInk8/+fxDLww3N/iuu4/+kCfsLine truncated
|
||||
"text/plain": [
|
||||
"<Figure size 864x864 with 1 Axes>"
|
||||
"<Figure size 864x432 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
@@ -1718,13 +1715,17 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"path = path_states(hill_climb(in12))\n",
|
||||
"\n",
|
||||
"square_plot(path, 'r-',\n",
|
||||
" extra=lambda: plt.scatter(*T(in12), c=list(in12.values()), \n",
|
||||
" cmap=plt.get_cmap('YlGn')))"
|
||||
"naked_plot(path_states(hill_climb(in12)), 'r-', size=(12, 6))\n",
|
||||
"plt.scatter(*T(in12), c=list(in12.values()), cmap=plt.get_cmap('YlGn'));"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
@@ -1768,7 +1769,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"in13 = parse(13, (lambda text: mapt(literal_eval, text.splitlines())), paragraphs)"
|
||||
"in13 = parse(13, (lambda text: mapt(ast.literal_eval, text.splitlines())), paragraphs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1777,7 +1778,7 @@
|
||||
"source": [
|
||||
"#### Part 1: Determine which pairs of packets are already in the right order. What is the sum of the indices of those pairs?\n",
|
||||
"\n",
|
||||
"The notion of \"right order\" is almost the same as \"less than\", except that an integer is equal to a singleton list. I was confused for a bit because the rules don't say whether two identical lists are in the right order or not. I decided that `right_order` should return `True` or `False` for inputs that are different, and `None` for inputs that are equal. "
|
||||
"The notion of \"right order\" is almost the same as \"less than\", except that an integer is equal to a singleton list. Also, I was confused for a bit because the rules don't say whether two identical lists are in the right order or not; the rules just say you should \"continue checking\" in that case. I decided that I should not define a Boolean truth predicate; rather it should be a *ternary* comparison function. By convention, a Python comparison function, `compare(left, right)`, returns a negative number if `left < right`, zero if they are equal, and a positive number if `left > right`. I'll implement that:"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1786,28 +1787,24 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def right_order(left, right) -> Union[bool, None]:\n",
|
||||
" \"\"\"Are the two packets in the right order? Return `None` if equal.\"\"\"\n",
|
||||
" types = type(left), type(right)\n",
|
||||
" if types == (int, int):\n",
|
||||
" return (None if left == right else left <= right)\n",
|
||||
" elif types == (int, list):\n",
|
||||
" return right_order([left], right)\n",
|
||||
" elif types == (list, int):\n",
|
||||
" return right_order(left, [right])\n",
|
||||
" else:\n",
|
||||
" for L, R in zip(left, right):\n",
|
||||
" result = right_order(L, R)\n",
|
||||
" if result != None:\n",
|
||||
" return result\n",
|
||||
" return (None if len(left) == len(right) else len(left) < len(right))"
|
||||
"def compare(left, right) -> int:\n",
|
||||
" \"\"\"Are the two packets in the right order? \n",
|
||||
" Negative number for right order; 0 for equal; positive for wrong order.\"\"\"\n",
|
||||
" types = (type(left), type(right))\n",
|
||||
" if types == (int, int): return left - right\n",
|
||||
" elif types == (int, list): return compare([left], right)\n",
|
||||
" elif types == (list, int): return compare(left, [right])\n",
|
||||
" elif types == (list, list): return first_true(map(compare, left, right), \n",
|
||||
" default=len(left) - len(right))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"That makes things pretty straightforward, but I threw in some test cases just to make sure: "
|
||||
"The call to `first_true` (from my [AdventUtils](AdventUtils.ipynb) or from [itertools recipes](https://docs.python.org/3/library/itertools.html#itertools-recipes)) says to `compare` respective successive elements of the two lists one by one, and to return the first true (i.e. non-zero) comparison, or if one of the two lists is exhausted first, return the comparison of the list lengths. \n",
|
||||
"\n",
|
||||
"I threw in some test cases to gain some confidence that I got it right: "
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1816,11 +1813,11 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert right_order([1,1,3,1,1], [1,1,5,1,1])\n",
|
||||
"assert right_order([[1],[2,3,4]], [[1],4])\n",
|
||||
"assert not right_order([7,7,7,7], [7,7,7]) \n",
|
||||
"assert not right_order([1,[2,[3,[4,[5,6,7]]]],8,9], [1,[2,[3,[4,[5,6,0]]]],8,9])\n",
|
||||
"assert right_order([1,2,3], [1,2,3]) == None"
|
||||
"assert compare([1,1,3,1,1], [1,1,5,1,1]) < 0\n",
|
||||
"assert compare([[1],[2,3,4]], [[1],4]) < 0\n",
|
||||
"assert compare([7,7,7,7], [7,7,7]) > 0 \n",
|
||||
"assert compare([1,[2,[3,[4,[5,6,7]]]],8,9], [1,[2,[3,[4,[5,6,0]]]],8,9]) > 0\n",
|
||||
"assert compare([1,2,3], [1,2,3]) == 0"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1839,12 +1836,12 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0.000 seconds for correct answer: 5,882\n"
|
||||
"0.001 seconds for correct answer: 5,882\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"answer(13.1, 5882, lambda: sum(i for i, (L, R) in enumerate(in13, 1) if right_order(L, R)))"
|
||||
"answer(13.1, 5882, lambda: sum(i for i, (L, R) in enumerate(in13, 1) if compare(L, R) < 0))"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1867,23 +1864,236 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0.007 seconds for correct answer: 24,948\n"
|
||||
"0.009 seconds for correct answer: 24,948\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def decode(packets, dividers=[[[2]],[[6]]]):\n",
|
||||
" \"\"\"Sort the packets and the dividers, and return their product of the indices of the dividers.\"\"\"\n",
|
||||
" ordered = sorted(append(packets) + dividers, key=functools.cmp_to_key(cmp_order))\n",
|
||||
" ordered = sorted(append(packets) + dividers, key=functools.cmp_to_key(compare))\n",
|
||||
" return prod(ordered.index(d) + 1 for d in dividers)\n",
|
||||
"\n",
|
||||
"def cmp_order(left, right) -> int:\n",
|
||||
" \"\"\"Call `right_order` and convert True/None/False to -1/0/+1.\"\"\"\n",
|
||||
" return {True: -1, None: 0, False: +1}[right_order(left, right)]\n",
|
||||
" \n",
|
||||
"answer(13.2, 24948, lambda: decode(in13))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# [Day 14](https://adventofcode.com/2022/day/14): Regolith Reservoir\n",
|
||||
"\n",
|
||||
"I happen to know that *regolith* is loose dust on the surface of a planet; the Apollo astronauts refered to the lunar regolith. I'm not sure if that will help with today's puzzle. \n",
|
||||
"\n",
|
||||
"The first task is to parse each line into a sequence of (x, y) points, representing the vertices of a zig-zag path:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 50,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
|
||||
"Puzzle input ➜ 163 lines:\n",
|
||||
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
|
||||
"494,71 -> 498,71\n",
|
||||
"490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,18 -> 492,23 -> 494,23 -> 494,16 -> 494,23 -> 496,23 ...\n",
|
||||
"472,131 -> 472,134 -> 466,134 -> 466,141 -> 484,141 -> 484,134 -> 476,134 -> 476,131\n",
|
||||
"490,23 -> 490,17 -> 490,23 -> 492,23 -> 492,18 -> 492,23 -> 494,23 -> 494,16 -> 494,23 -> 496,23 ...\n",
|
||||
"478,104 -> 478,103 -> 478,104 -> 480,104 -> 480,96 -> 480,104 -> 482,104 -> 482,97 -> 482,104 -> ...\n",
|
||||
"469,53 -> 474,53\n",
|
||||
"...\n",
|
||||
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
|
||||
"Parsed representation ➜ 163 lists:\n",
|
||||
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
|
||||
"[(494, 71), (498, 71)]\n",
|
||||
"[(490, 23), (490, 17), (490, 23), (492, 23), (492, 18), (492, 23), (494, 23), (494, 16), (494, 2 ...\n",
|
||||
"[(472, 131), (472, 134), (466, 134), (466, 141), (484, 141), (484, 134), (476, 134), (476, 131)]\n",
|
||||
"[(490, 23), (490, 17), (490, 23), (492, 23), (492, 18), (492, 23), (494, 23), (494, 16), (494, 2 ...\n",
|
||||
"[(478, 104), (478, 103), (478, 104), (480, 104), (480, 96), (480, 104), (482, 104), (482, 97), ( ...\n",
|
||||
"[(469, 53), (474, 53)]\n",
|
||||
"...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"in14 = parse(14, lambda line: batched(ints(line), 2))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Part 1: Using your scan, simulate the falling sand. How many units of sand come to rest before sand starts flowing into the abyss below?\n",
|
||||
"\n",
|
||||
"Now we have to simulate the movement of each particle of falling sand as they slide downwards. The particles prefer to go straight downwards (South), but if that location is occupied they will go diagonally Southwest, and if that is occupied, Southeast. If all three are blocked, they stop. The simulation continues until one particle falls off the bottom. At that point, we return the number of particles that have come to rest (not counting the one that fell off the bottom).\n",
|
||||
"\n",
|
||||
"I'll just return the number of time steps, but because Part 2 might want some more information, I'll have my `simulate_sand` function accept a grid as input and modify the grid. Perhaps in Part 2 we'll want to take a look at how the grid was modified."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 51,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0.136 seconds for correct answer: 728\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def put_lines(grid, lines) -> Grid:\n",
|
||||
" \"Place the lines of rock onto the grid.\"\n",
|
||||
" for line in lines:\n",
|
||||
" for ((x0, y0), (x1, y1)) in sliding_window(line, 2):\n",
|
||||
" for p in cross_product(cover(x0, x1), cover(y0, y1)):\n",
|
||||
" grid[p] = '#'\n",
|
||||
" return grid\n",
|
||||
"\n",
|
||||
"def simulate_sand(grid, lines, entry=(500, 0)) -> int:\n",
|
||||
" put_lines(grid, lines)\n",
|
||||
" bottom = max(map(Y_, grid)) # The bottom-most piece of rock\n",
|
||||
" falling = [South, add(South, West), add(South, East)] # The directions sand can fall\n",
|
||||
" for t in count_from(1):\n",
|
||||
" loc = entry # A new sand particle enters\n",
|
||||
" while True: # ... and falls\n",
|
||||
" points = [add(loc, dir) for dir in falling]\n",
|
||||
" loc2 = first((p for p in points if p not in grid), default=loc)\n",
|
||||
" if loc == loc2: # Sand comes to rest\n",
|
||||
" grid[loc] = 'o'\n",
|
||||
" break\n",
|
||||
" elif Y_(loc) > bottom: # Sand falls into endless void\n",
|
||||
" return t - 1\n",
|
||||
" loc = loc2\n",
|
||||
"\n",
|
||||
"answer(14.1, 728, lambda: simulate_sand(Grid(), in14))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"I'm ashamed to say the first time I ran this, I got an infinite loop; I had neglected to include the `loc = loc2` line at the end of the function. I knew I had to do that; I just forgot. And I guess I prefer to think functionally, not in terms of updates, so I messed up. After correcting for that, I had an off-by-one error, because I misread the instructions and thought the last unit of sand, which falls into the void, should be counted, but it should not."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Part 2: Using your scan, simulate the falling sand until the source of the sand becomes blocked. How many units of sand come to rest?\n",
|
||||
"\n",
|
||||
"In Part 2, the sand no longer falls off the bottom; instead there is a *floor* at the bottom of the cave (specified as 2 units below the deepest known rock line). Since the [angle of repose](https://en.wikipedia.org/wiki/Angle_of_repose) of the sand is 45°, we need to make the floor wide enough to cover that (and throw in a bit extra to make sure; I added \"2\" to the `dx` variable, which tells how far away from the entry point the floor needs to extend). Eventually the sand will back up and cover the entry point; that's a second way to end the simulation.\n",
|
||||
"\n",
|
||||
"I'll re-write `simulate_sand` so that it handles both ways to end the simulation. If you want the Part 1 way, specify `floor=0` (the default); this means there is no floor. If you want the Part 2 way, specify, say, `floor=2` to put the floor two units below the lowest rock."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 52,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"0.136 seconds for correct answer: 728\n",
|
||||
"6.396 seconds for correct answer: 27,623\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def simulate_sand(grid, lines, entry=(500, 0), floor=0) -> int:\n",
|
||||
" put_lines(grid, lines)\n",
|
||||
" Ymax = max(map(Y_, grid)) + floor # Y-coordinate of the floor\n",
|
||||
" falling = [South, add(South, West), add(South, East)] # The directions sand can fall\n",
|
||||
" if floor: # put down a floor line that is wide enough to catch anything from the entry\n",
|
||||
" x, dx = X_(entry), Ymax + 2\n",
|
||||
" put_lines(grid, [[(x - dx, Ymax), (x + dx, Ymax)]]) \n",
|
||||
" for t in count_from(1):\n",
|
||||
" loc = entry # A new sand particle enters\n",
|
||||
" while True: # The sand particle falls\n",
|
||||
" points = [add(loc, dir) for dir in falling]\n",
|
||||
" loc2 = first((p for p in points if p not in grid), default=loc)\n",
|
||||
" if loc2 == entry: # Stop if the entry point is blocked\n",
|
||||
" return t\n",
|
||||
" if loc == loc2: # Sand comes to rest\n",
|
||||
" grid[loc2] = 'o'\n",
|
||||
" break\n",
|
||||
" elif Y_(loc2) > Ymax: # Sand falls into endless void\n",
|
||||
" grid[loc2] = 'o'\n",
|
||||
" return t - 1\n",
|
||||
" loc = loc2\n",
|
||||
" \n",
|
||||
"answer(14.1, 728, lambda: simulate_sand(Grid(), in14))\n",
|
||||
"answer(14.2, 27623, lambda: simulate_sand(Grid(), in14, floor=2))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Uh, oh! Up to now my solutions have been speedy enough, but this one takes 6 seconds, 20 times worse than the slowest solution so far. I hope the coming days don't continue this trend.\n",
|
||||
"\n",
|
||||
"#### Part 3: Exploration\n",
|
||||
"\n",
|
||||
"Let's get a picture of the rock lines and the accumulated sand. (I didn't need access to the grid for Part 2, but now I'm glad to have it)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 53,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 360x1080 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"grid = Grid({(500, 0): '+'})\n",
|
||||
"simulate_sand(grid, in14)\n",
|
||||
"grid.plot({'+': 'rD', 'o': 'y.', '#': 'b|'}, figsize=(5, 15))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 54,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1440x720 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"grid2 = Grid({(500, 0): '+'})\n",
|
||||
"simulate_sand(grid2, in14, floor=2)\n",
|
||||
"grid2.plot({'+': 'rD', 'o': 'y,', '#': 'b|'}, figsize=(20, 10))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
@@ -1895,7 +2105,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 50,
|
||||
"execution_count": 55,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@@ -1905,7 +2115,7 @@
|
||||
" 1.2: '0.000 seconds for correct answer: 206,582',\n",
|
||||
" 2.1: '0.001 seconds for correct answer: 13,268',\n",
|
||||
" 2.2: '0.001 seconds for correct answer: 15,508',\n",
|
||||
" 3.1: '0.001 seconds for correct answer: 8,401',\n",
|
||||
" 3.1: '0.000 seconds for correct answer: 8,401',\n",
|
||||
" 3.2: '0.000 seconds for correct answer: 2,641',\n",
|
||||
" 4.1: '0.000 seconds for correct answer: 477',\n",
|
||||
" 4.2: '0.000 seconds for correct answer: 830',\n",
|
||||
@@ -1916,20 +2126,22 @@
|
||||
" 7.1: '0.001 seconds for correct answer: 1,232,307',\n",
|
||||
" 7.2: '0.001 seconds for correct answer: 7,268,994',\n",
|
||||
" 8.1: '0.050 seconds for correct answer: 1,829',\n",
|
||||
" 8.2: '0.055 seconds for correct answer: 291,840',\n",
|
||||
" 9.1: '0.023 seconds for correct answer: 6,236',\n",
|
||||
" 9.2: '0.108 seconds for correct answer: 2,449',\n",
|
||||
" 8.2: '0.057 seconds for correct answer: 291,840',\n",
|
||||
" 9.1: '0.024 seconds for correct answer: 6,236',\n",
|
||||
" 9.2: '0.112 seconds for correct answer: 2,449',\n",
|
||||
" 10.1: '0.000 seconds for correct answer: 12,560',\n",
|
||||
" 10.2: '0.012 seconds for correct answer: PLPAFBCL',\n",
|
||||
" 10.2: '0.036 seconds for correct answer: PLPAFBCL',\n",
|
||||
" 11.1: '0.001 seconds for correct answer: 54,036',\n",
|
||||
" 11.2: '0.282 seconds for correct answer: 13,237,873,355',\n",
|
||||
" 12.1: '0.036 seconds for correct answer: 394',\n",
|
||||
" 12.2: '0.039 seconds for correct answer: 388',\n",
|
||||
" 13.1: '0.000 seconds for correct answer: 5,882',\n",
|
||||
" 13.2: '0.007 seconds for correct answer: 24,948'}"
|
||||
" 11.2: '0.278 seconds for correct answer: 13,237,873,355',\n",
|
||||
" 12.1: '0.039 seconds for correct answer: 394',\n",
|
||||
" 12.2: '0.038 seconds for correct answer: 388',\n",
|
||||
" 13.1: '0.001 seconds for correct answer: 5,882',\n",
|
||||
" 13.2: '0.009 seconds for correct answer: 24,948',\n",
|
||||
" 14.1: '0.136 seconds for correct answer: 728',\n",
|
||||
" 14.2: '6.396 seconds for correct answer: 27,623'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 50,
|
||||
"execution_count": 55,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
|
||||
+183
-113
@@ -13,7 +13,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -24,16 +24,17 @@
|
||||
"from typing import *\n",
|
||||
"from statistics import mean, median\n",
|
||||
"from math import ceil, floor, factorial, gcd, log, log2, log10, sqrt, inf\n",
|
||||
"from functools import reduce\n",
|
||||
"\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import time\n",
|
||||
"import heapq\n",
|
||||
"import string\n",
|
||||
"\n",
|
||||
"import ast\n",
|
||||
"import functools\n",
|
||||
"import heapq\n",
|
||||
"import operator\n",
|
||||
"import pathlib\n",
|
||||
"import re"
|
||||
"import re\n",
|
||||
"import string\n",
|
||||
"import time"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -55,12 +56,12 @@
|
||||
"- **Part 2**: Repeat the above steps for Part 2.\n",
|
||||
"- Occasionally I'll introduce a **Part 3** where I explore beyond the official instructions.\n",
|
||||
"\n",
|
||||
"Here is `parse` and some helper functions for it:"
|
||||
"Here is `parse`:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -108,14 +109,19 @@
|
||||
" return lambda section: next(fns)(section)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Functions that can be used as the `parser` argument to `parse` (also, consider `str.split` to split the line on whitespace): "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"## Functions that can be used by `parse`\n",
|
||||
"\n",
|
||||
"Char = str # Intended as the type of a one-character string\n",
|
||||
"Atom = Union[str, float, int] # The type of a string or number\n",
|
||||
"\n",
|
||||
@@ -147,9 +153,16 @@
|
||||
" except ValueError:\n",
|
||||
" return text.strip()\n",
|
||||
" \n",
|
||||
"def mapt(function: Callable, sequence) -> tuple:\n",
|
||||
"def mapt(function: Callable, *sequences) -> tuple:\n",
|
||||
" \"\"\"`map`, with the result as a tuple.\"\"\"\n",
|
||||
" return tuple(map(function, sequence))"
|
||||
" return tuple(map(function, *sequences))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Some tests for the functions above:"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -158,8 +171,6 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"## TESTS\n",
|
||||
"\n",
|
||||
"assert parse(\"hello\\nworld\", show=0) == ('hello', 'world')\n",
|
||||
"assert parse(\"123\\nabc7\", digits, show=0) == ((1, 2, 3), (7,))\n",
|
||||
"assert truncate('hello world', 99) == 'hello world'\n",
|
||||
@@ -196,9 +207,9 @@
|
||||
" def pretty(x): return f'{x:,d}' if is_int(x) else truncate(x)\n",
|
||||
" start = time.time()\n",
|
||||
" got = code()\n",
|
||||
" dt = time.time() - start\n",
|
||||
" secs = time.time() - start\n",
|
||||
" ans = pretty(got)\n",
|
||||
" msg = f'{dt:5.3f} seconds for ' + (\n",
|
||||
" msg = f'{secs:5.3f} seconds for ' + (\n",
|
||||
" f'correct answer: {ans}' if (got == correct) else\n",
|
||||
" f'WRONG!! ANSWER: {ans}; EXPECTED {pretty(correct)}')\n",
|
||||
" answers[puzzle] = msg\n",
|
||||
@@ -216,14 +227,10 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def quantify(iterable, pred=bool) -> int:\n",
|
||||
" \"\"\"Count the number of items in iterable for which pred is true.\"\"\"\n",
|
||||
" return sum(1 for item in iterable if pred(item))\n",
|
||||
"\n",
|
||||
"class multimap(defaultdict):\n",
|
||||
" \"\"\"A mapping of {key: [val1, val2, ...]}.\"\"\"\n",
|
||||
" def __init__(self, pairs: Iterable[tuple], symmetric=False):\n",
|
||||
@@ -242,6 +249,10 @@
|
||||
" result *= x\n",
|
||||
" return result\n",
|
||||
"\n",
|
||||
"def T(matrix: Sequence[Sequence]) -> List[Tuple]:\n",
|
||||
" \"\"\"The transpose of a matrix: T([(1,2,3), (4,5,6)]) == [(1,4), (2,5), (3,6)]\"\"\"\n",
|
||||
" return list(zip(*matrix))\n",
|
||||
"\n",
|
||||
"def total(counter: Counter) -> int: \n",
|
||||
" \"\"\"The sum of all the counts in a Counter.\"\"\"\n",
|
||||
" return sum(counter.values())\n",
|
||||
@@ -251,14 +262,6 @@
|
||||
" numbers = list(numbers)\n",
|
||||
" return min(numbers), max(numbers)\n",
|
||||
"\n",
|
||||
"def first(iterable) -> Optional[object]: \n",
|
||||
" \"\"\"The first element in an iterable, or None.\"\"\"\n",
|
||||
" return next(iter(iterable), None)\n",
|
||||
"\n",
|
||||
"def T(matrix: Sequence[Sequence]) -> List[Tuple]:\n",
|
||||
" \"\"\"The transpose of a matrix: T([(1,2,3), (4,5,6)]) == [(1,4), (2,5), (3,6)]\"\"\"\n",
|
||||
" return list(zip(*matrix))\n",
|
||||
"\n",
|
||||
"def cover(*integers) -> range:\n",
|
||||
" \"\"\"A `range` that covers all the given integers, and any in between them.\n",
|
||||
" cover(lo, hi) is a an inclusive (or closed) range, equal to range(lo, hi + 1).\"\"\"\n",
|
||||
@@ -275,6 +278,93 @@
|
||||
" \"\"\"The sequence split into two pieces: (before position i, and i-and-after).\"\"\"\n",
|
||||
" return sequence[:i], sequence[i:]\n",
|
||||
"\n",
|
||||
"def ignore(*args) -> None: \"Just return None.\"; return None\n",
|
||||
"\n",
|
||||
"def is_int(x) -> bool: \"Is x an int?\"; return isinstance(x, int) \n",
|
||||
"\n",
|
||||
"def sign(x) -> int: \"0, +1, or -1\"; return (0 if x == 0 else +1 if x > 0 else -1)\n",
|
||||
"\n",
|
||||
"def union(sets) -> set: \"Union of several sets\"; return set().union(*sets)\n",
|
||||
"\n",
|
||||
"def intersection(sets):\n",
|
||||
" \"Intersection of several sets; error if no sets.\"\n",
|
||||
" first, *rest = sets\n",
|
||||
" return set(first).intersection(*rest)\n",
|
||||
" \n",
|
||||
"def naked_plot(points, marker='o', size=(10, 10), invert=True, square=False, **kwds):\n",
|
||||
" \"\"\"Plot `points` without any axis lines or tick marks.\n",
|
||||
" Optionally specify size, whether square or not, and whether to invery y axis.\"\"\"\n",
|
||||
" if size: plt.figure(figsize=((size, size) if is_int(size) else size))\n",
|
||||
" plt.plot(*T(points), marker, **kwds)\n",
|
||||
" if square: plt.axis('square')\n",
|
||||
" plt.axis('off')\n",
|
||||
" if invert: plt.gca().invert_yaxis()\n",
|
||||
" \n",
|
||||
"def clock_mod(i, m) -> int:\n",
|
||||
" \"\"\"i % m, but replace a result of 0 with m\"\"\"\n",
|
||||
" # This is like a clock, where 24 mod 12 is 12, not 0.\n",
|
||||
" return (i % m) or m\n",
|
||||
"\n",
|
||||
"cat = ''.join\n",
|
||||
"cache = functools.lru_cache(None)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"More tests:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert multimap(((i % 3), i) for i in range(9)) == {0: [0, 3, 6], 1: [1, 4, 7], 2: [2, 5, 8]}\n",
|
||||
"assert prod([2, 3, 5]) == 30\n",
|
||||
"assert total(Counter('hello, world')) == 12\n",
|
||||
"assert cover(3, 1, 4, 1, 5) == range(1, 6)\n",
|
||||
"assert minmax([3, 1, 4, 1, 5, 9]) == (1, 9)\n",
|
||||
"assert T([(1, 2, 3), (4, 5, 6)]) == [(1, 4), (2, 5), (3, 6)]\n",
|
||||
"assert the({1}) == 1\n",
|
||||
"assert split_at('hello, world', 6) == ('hello,', ' world')\n",
|
||||
"assert is_int(-42) and not is_int('one')\n",
|
||||
"assert sign(-42) == -1 and sign(0) == 0 and sign(42) == +1\n",
|
||||
"assert union([{1, 2}, {3, 4}, {5, 6}]) == {1, 2, 3, 4, 5, 6}\n",
|
||||
"assert intersection([{1, 2, 3}, {2, 3, 4}, {2, 4, 6, 8}]) == {2}\n",
|
||||
"assert clock_mod(24, 12) == 12 and 24 % 12 == 0\n",
|
||||
"assert cat(['hello', 'world']) == 'helloworld'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Itertools Recipes\n",
|
||||
"\n",
|
||||
"The Python docs for the `itertools` module has some [\"recipes\"](https://docs.python.org/3/library/itertools.html#itertools-recipes) that I include here (some I have slightly modified):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def quantify(iterable, pred=bool) -> int:\n",
|
||||
" \"\"\"Count the number of items in iterable for which pred is true.\"\"\"\n",
|
||||
" return sum(1 for item in iterable if pred(item))\n",
|
||||
"\n",
|
||||
"def dotproduct(vec1, vec2):\n",
|
||||
" \"\"\"The dot product of two vectors.\"\"\"\n",
|
||||
" return sum(map(operator.mul, vec1, vec2))\n",
|
||||
"\n",
|
||||
"flatten = chain.from_iterable # Yield items from each sequence in turn\n",
|
||||
"\n",
|
||||
"def append(sequences) -> Sequence: \"Append into a list\"; return list(flatten(sequences))\n",
|
||||
"\n",
|
||||
"def batched(data, n) -> list:\n",
|
||||
" \"Batch data into lists of length n. The last batch may be shorter.\"\n",
|
||||
" # batched('ABCDEFG', 3) --> ABC DEF G\n",
|
||||
@@ -284,68 +374,37 @@
|
||||
" \"\"\"All length-n subsequences of sequence.\"\"\"\n",
|
||||
" return (sequence[i:i+n] for i in range(len(sequence) + 1 - n))\n",
|
||||
"\n",
|
||||
"def ignore(*args) -> None: \"Just return None.\"; return None\n",
|
||||
"def first(iterable, default=None) -> Optional[object]: \n",
|
||||
" \"\"\"The first element in an iterable, or the default if iterable is empty.\"\"\"\n",
|
||||
" return next(iter(iterable), default)\n",
|
||||
"\n",
|
||||
"def is_int(x) -> bool: \"Is x an int?\"; return isinstance(x, int) \n",
|
||||
"\n",
|
||||
"def sign(x) -> int: \"0, +1, or -1\"; return (0 if x == 0 else +1 if x > 0 else -1)\n",
|
||||
"\n",
|
||||
"def append(sequences) -> Sequence: \"Append sequences into a list\"; return list(flatten(sequences))\n",
|
||||
"\n",
|
||||
"def union(sets) -> set: \"Union of several sets\"; return set().union(*sets)\n",
|
||||
"\n",
|
||||
"def intersection(sets):\n",
|
||||
" \"Intersection of several sets.\"\n",
|
||||
" first, *rest = sets\n",
|
||||
" return set(first).intersection(*rest)\n",
|
||||
"\n",
|
||||
"def square_plot(points, marker='o', size=12, extra=None, **kwds):\n",
|
||||
" \"\"\"Plot `points` in a square of given `size`, with no axis labels.\n",
|
||||
" Calls `extra()` to do more plt.* stuff if defined.\"\"\"\n",
|
||||
" plt.figure(figsize=(size, size))\n",
|
||||
" plt.plot(*T(points), marker, **kwds)\n",
|
||||
" if extra: extra()\n",
|
||||
" plt.axis('square'); plt.axis('off'); plt.gca().invert_yaxis()\n",
|
||||
" \n",
|
||||
"def clock_mod(i, m) -> int:\n",
|
||||
" \"\"\"i % m, but replace a result of 0 with m\"\"\"\n",
|
||||
" # This is like a clock, where 24 mod 12 is 12, not 0.\n",
|
||||
" return (i % m) or m\n",
|
||||
"\n",
|
||||
"flatten = chain.from_iterable # Yield items from each sequence in turn\n",
|
||||
"cat = ''.join\n",
|
||||
"cache = functools.lru_cache(None)"
|
||||
"def first_true(iterable, default=False):\n",
|
||||
" \"\"\"Returns the first true value in the iterable.\n",
|
||||
" If no true value is found, returns `default`.\"\"\"\n",
|
||||
" return next((x for x in iterable if x), default)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"More tests:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"## TESTS\n",
|
||||
"\n",
|
||||
"assert quantify(words('This is a test'), str.islower) == 3\n",
|
||||
"assert mapt(first, words('This is a test')) == ('T', 'i', 'a', 't')\n",
|
||||
"assert multimap(((i % 3), i) for i in range(9)) == {0: [0, 3, 6], 1: [1, 4, 7], 2: [2, 5, 8]}\n",
|
||||
"assert prod([2, 3, 5]) == 30\n",
|
||||
"assert total(Counter('hello, world')) == 12\n",
|
||||
"assert cover(3, 1, 4, 1, 5) == range(1, 6)\n",
|
||||
"assert minmax([3, 1, 4, 1, 5, 9]) == (1, 9)\n",
|
||||
"assert first('abc') == 'a'\n",
|
||||
"assert T([(1, 2, 3), (4, 5, 6)]) == [(1, 4), (2, 5), (3, 6)]\n",
|
||||
"assert the({1}) == 1\n",
|
||||
"assert split_at('hello, world', 6) == ('hello,', ' world')\n",
|
||||
"assert dotproduct([1, 2, 3, 4], [1000, 100, 10, 1]) == 1234\n",
|
||||
"assert list(flatten([{1, 2, 3}, (4, 5, 6), [7, 8, 9]])) == [1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
|
||||
"assert append(([1, 2], [3, 4], [5, 6])) == [1, 2, 3, 4, 5, 6]\n",
|
||||
"assert batched('abcdefghi', 3) == ['abc', 'def', 'ghi']\n",
|
||||
"assert list(sliding_window('abcdefghi', 3)) == ['abc', 'bcd', 'cde', 'def', 'efg', 'fgh', 'ghi']\n",
|
||||
"assert is_int(-42) and not is_int('one')\n",
|
||||
"assert sign(-42) == -1 and sign(0) == 0 and sign(42) == +1\n",
|
||||
"assert append(([1, 2], [3, 4], [5, 6])) == [1, 2, 3, 4, 5, 6]\n",
|
||||
"assert union([{1, 2}, {3, 4}, {5, 6}]) == {1, 2, 3, 4, 5, 6}\n",
|
||||
"assert intersection([{1, 2, 3}, {2, 3, 4}, {2, 4, 6, 8}]) == {2}\n",
|
||||
"assert clock_mod(24, 12) == 12 and 24 % 12 == 0\n",
|
||||
"assert list(flatten(['abc', 'def', '123'])) == ['a', 'b', 'c', 'd', 'e', 'f', '1', '2', '3']\n",
|
||||
"assert cat(['hello', 'world']) == 'helloworld'"
|
||||
"assert first('abc') == 'a'\n",
|
||||
"assert first_true([0, None, False, 42, 99]) == 42"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -359,7 +418,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -391,39 +450,21 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"## TESTS\n",
|
||||
"\n",
|
||||
"p, q = (0, 3), (4, 0)\n",
|
||||
"assert Y_(p) == 3 and X_(q) == 4\n",
|
||||
"assert distance(p, q) == 5\n",
|
||||
"assert manhatten_distance(p, q) == 7\n",
|
||||
"assert add(p, q) == (4, 3)\n",
|
||||
"assert sub(p, q) == (-4, 3)\n",
|
||||
"assert add(North, South) == (0,0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Grid(dict):\n",
|
||||
" \"\"\"A 2D grid, implemented as a mapping of {(x, y): cell_contents}.\"\"\"\n",
|
||||
" def __init__(self, mapping_or_rows, directions=directions4):\n",
|
||||
" def __init__(self, mapping_or_rows=(), directions=directions4):\n",
|
||||
" \"\"\"Initialize with either (e.g.) `Grid({(0, 0): 1, (1, 0): 2, ...})`, or\n",
|
||||
" `Grid([(1, 2, 3), (4, 5, 6)]).\"\"\"\n",
|
||||
" self.directions = directions\n",
|
||||
" self.update(mapping_or_rows if isinstance(mapping_or_rows, abc.Mapping) else\n",
|
||||
" {(x, y): val \n",
|
||||
" for y, row in enumerate(mapping_or_rows) \n",
|
||||
" for x, val in enumerate(row)})\n",
|
||||
" self.width = max(map(X_, self)) + 1\n",
|
||||
" self.height = max(map(Y_, self)) + 1\n",
|
||||
" self.directions = directions\n",
|
||||
"\n",
|
||||
" \n",
|
||||
" def copy(self): return Grid(self, directions=self.directions)\n",
|
||||
" \n",
|
||||
@@ -431,14 +472,43 @@
|
||||
" \"\"\"Points on the grid that neighbor `point`.\"\"\"\n",
|
||||
" return [add(point, Δ) for Δ in self.directions if add(point, Δ) in self]\n",
|
||||
" \n",
|
||||
" def to_rows(self, default='.') -> List[List[object]]:\n",
|
||||
" def to_rows(self, default='.', Xs=None, Ys=None) -> List[List[object]]:\n",
|
||||
" \"\"\"The contents of the grid in a rectangular list of lists.\"\"\"\n",
|
||||
" return [[self.get((x, y), default) for x in range(self.width)]\n",
|
||||
" for y in range(self.height)]\n",
|
||||
" Xs = Xs or range(max(map(X_, self)) + 1)\n",
|
||||
" Ys = Ys or range(max(map(Y_, self)) + 1)\n",
|
||||
" return [[self.get((x, y), default) for x in Xs] for y in Ys]\n",
|
||||
" \n",
|
||||
" def to_picture(self, sep='', default='.') -> str:\n",
|
||||
" \"\"\"The contents of the grid as a picture.\"\"\"\n",
|
||||
" return '\\n'.join(map(cat, self.to_rows(default)))"
|
||||
" def to_picture(self, sep='', default='.', Xs=None, Ys=None) -> str:\n",
|
||||
" \"\"\"The contents of the grid as a picture. Youi can specify the `Xs` and `Ys` to include.\"\"\"\n",
|
||||
" return '\\n'.join(map(sep.join, self.to_rows(default, Xs, Ys)))\n",
|
||||
" \n",
|
||||
" def plot(self, markers, figsize=(14, 14), **kwds):\n",
|
||||
" plt.figure(figsize=figsize)\n",
|
||||
" plt.gca().invert_yaxis()\n",
|
||||
" for m in markers:\n",
|
||||
" plt.plot(*T(p for p in self if self[p] == m), markers.get(m, m), **kwds)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Tests:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"p, q = (0, 3), (4, 0)\n",
|
||||
"assert Y_(p) == 3 and X_(q) == 4\n",
|
||||
"assert distance(p, q) == 5\n",
|
||||
"assert manhatten_distance(p, q) == 7\n",
|
||||
"assert add(p, q) == (4, 3)\n",
|
||||
"assert sub(p, q) == (-4, 3)\n",
|
||||
"assert add(North, South) == (0,0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -452,7 +522,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -480,7 +550,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -545,7 +615,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
||||
Reference in new issue
Block a user