This commit is contained in:
Peter Norvig authored and GitHub committed 2022-12-10 15:12:18 -08:00
1 parent dee0d1700b
commit 4fc1bc23f7
1 file changed
+611 -101
+611 -101
View File
@@ -21,20 +21,7 @@
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'mapt' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m~/Google Drive/Python/AdventUtils.ipynb\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m## TESTS\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0mparse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"hello\\nworld\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshow\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m'hello'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'world'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0mparse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"123\\nabc7\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdigits\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshow\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m7\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0mtruncate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'hello world'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m99\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'hello world'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Google Drive/Python/AdventUtils.ipynb\u001b[0m in \u001b[0;36mparse\u001b[0;34m(day_or_text, parser, sep, show)\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mtext\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_text\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mday_or_text\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mprint_parse_items\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Puzzle input'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtext\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplitlines\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshow\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'line'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0mrecords\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmapt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparser\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtext\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrstrip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msep\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 11\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mparser\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0mprint_parse_items\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Parsed representation'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrecords\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshow\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34mf'{type(records[0]).__name__}'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mNameError\u001b[0m: name 'mapt' is not defined"
]
}
],
"outputs": [],
"source": [
"%run AdventUtils.ipynb"
]
@@ -80,20 +67,18 @@
"14614\n",
"\n",
"4829\n",
"...\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Parsed representation ➜ 268 tuples:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"(15931, 8782, 16940, 14614)\n",
"(4829, 12415, 13259, 11441, 8199)\n",
"(2540, 2500, 6341, 2235, 1858, 4157, 5053, 6611, 1050, 4401, 6187, 1078, 3297)\n",
"(25264, 23014, 15952)\n",
"(10156, 4544, 4930, 11786, 15822)\n",
"(1264, 6399, 2031, 6892, 3115, 5151, 5093, 6724, 7001, 4011, 1458, 1945)\n",
"...\n"
]
},
{
"ename": "NameError",
"evalue": "name 'mapt' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-2-dd26501d74ae>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0min1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mparse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mints\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparagraphs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-1-8de51a529160>\u001b[0m in \u001b[0;36mparse\u001b[0;34m(day_or_text, parser, sep, show)\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mtext\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_text\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mday_or_text\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mprint_parse_items\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Puzzle input'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtext\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplitlines\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshow\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'line'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0mrecords\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmapt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparser\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtext\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrstrip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msep\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 11\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mparser\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0mprint_parse_items\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Parsed representation'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrecords\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshow\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34mf'{type(records[0]).__name__}'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mNameError\u001b[0m: name 'mapt' is not defined"
]
}
],
"source": [
@@ -111,9 +96,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.000 seconds for correct answer: 70,116'"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"answer(1.1, 70116, lambda: max(sum(elf) for elf in in1))"
]
@@ -129,9 +125,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.000 seconds for correct answer: 206,582'"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"answer(1.2, 206582, lambda: sum(sorted(sum(elf) for elf in in1)[-3:]))"
]
@@ -168,9 +175,36 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 5,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Puzzle input ➜ 2500 lines:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"C Y\n",
"B Z\n",
"B Z\n",
"C Y\n",
"B Y\n",
"C Z\n",
"...\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Parsed representation ➜ 2500 tuples:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"('C', 'Y')\n",
"('B', 'Z')\n",
"('B', 'Z')\n",
"('C', 'Y')\n",
"('B', 'Y')\n",
"('C', 'Z')\n",
"...\n"
]
}
],
"source": [
"in2 = parse(2, atoms)"
]
@@ -186,9 +220,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.001 seconds for correct answer: 13,268'"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"RPS = Rock, Paper, Scissors = 1, 2, 3\n",
"rps_winner = {Rock: Paper, Paper: Scissors, Scissors: Rock}\n",
@@ -211,9 +256,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 7,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.001 seconds for correct answer: 15,508'"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rps_loser = {rps_winner[x]: x for x in RPS} # Invert the dict\n",
"\n",
@@ -236,9 +292,26 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 8,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Puzzle input ➜ 300 lines:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"lflZfgnSnlmmlgGfjGthQPtLNsQhvbHLLpSS\n",
"zrCVDVFMJTCTcCJMwCThWbtbpbWpPbtbHPLQssLsHP\n",
"rBFcrwFzFwwVDcDrzTzJfnRGjllBdGZnnZfhqmdn\n",
"FjpnFRDmbRtnbJrFJmSTsGShWVhGqGVVsmqs\n",
"ZwPvNPdzNZwfzBNLdNNNNcLvhnQhqMTVsTGSWSqGqTdVWhMT\n",
"vgLZHfvLffNLPbggnrbFpJnCbC\n",
"...\n"
]
}
],
"source": [
"in3 = parse(3)"
]
@@ -254,9 +327,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 9,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.001 seconds for correct answer: 8,401'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def common_item(rucksack: str) -> Char:\n",
" \"\"\"The one letter that appears in both left and right halves of the input string.\"\"\"\n",
@@ -279,9 +363,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 10,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.000 seconds for correct answer: 2,641'"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"answer(3.2, 2641, lambda: sum(priority[the(intersection(group))] for group in batched(in3, 3)))"
]
@@ -304,9 +399,36 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 11,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Puzzle input ➜ 1000 lines:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"18-20,19-21\n",
"9-86,9-87\n",
"7-8,8-18\n",
"82-98,98-99\n",
"17-17,17-77\n",
"13-21,20-79\n",
"...\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Parsed representation ➜ 1000 tuples:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"(18, 20, 19, 21)\n",
"(9, 86, 9, 87)\n",
"(7, 8, 8, 18)\n",
"(82, 98, 98, 99)\n",
"(17, 17, 17, 77)\n",
"(13, 21, 20, 79)\n",
"...\n"
]
}
],
"source": [
"in4 = parse(4, positive_ints)"
]
@@ -322,9 +444,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 12,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.000 seconds for correct answer: 477'"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def fully_contained(lo, hi, LO, HI) -> bool:\n",
" \"\"\"Is the range `lo-hi` fully contained in `LO-HI`, or vice-veresa?\"\"\"\n",
@@ -342,9 +475,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 13,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.000 seconds for correct answer: 830'"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def overlaps(lo, hi, LO, HI) -> bool:\n",
" \"\"\"Do the two ranges have any overlap?\"\"\"\n",
@@ -366,9 +510,37 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 14,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Puzzle input ➜ 513 lines:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
" [B] [L] [S]\n",
" [Q] [J] [C] [W] [F]\n",
" [F] [T] [B] [D] [P] [P]\n",
" [S] [J] [Z] [T] [B] [C] [H]\n",
" [L] [H] [H] [Z] [G] [Z] [G] [R]\n",
"[R] [H] [D] [R] [F] [C] [V] [Q] [T]\n",
"[C] [J] [M] [G] [P] [H] [N] [J] [D]\n",
"[H] [B] [R] [S] [R] [T] [S] [R] [L]\n",
" 1 2 3 4 5 6 7 8 9 \n",
"\n",
"move 8 from 7 to 1\n",
"move 9 from 1 to 9\n",
"...\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Parsed representation ➜ 2 tuples:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"(' B L S', ' QJC W F', ' FTBD P P', ' SJZT BCH', ' LHHZGZGR', 'RHDRFCVQT', 'CJMGPHNJD', 'HBR ...\n",
"((8, 7, 1), (9, 1, 9), (4, 5, 4), (4, 6, 1), (3, 8, 5), (6, 5, 9), (1, 5, 1), (4, 4, 9), (7, 3, ...\n"
]
}
],
"source": [
"in5 = parse(5, parse_sections([lambda line: line[1::4], ints]), sep=paragraphs, show=12)"
]
@@ -384,9 +556,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 15,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.001 seconds for correct answer: SHQWSRBDL'"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def rearrange(diagram, moves) -> str:\n",
" \"\"\"Given a diagram of crates in stacks, apply move commands.\n",
@@ -411,9 +594,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 16,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.000 seconds for correct answer: CDTQZHBRS'"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def rearrange(diagram, moves, model=9000) -> str:\n",
" stacks = {int(row[-1]): [L for L in row[-1::-1] if L != ' '] for row in T(diagram)}\n",
@@ -438,9 +632,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 17,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Puzzle input ➜ 1 line:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"qzbzwwghwhwdhdqhhbhfbfsstggdsssgzgdzzdbbbzmbzzvlldppjnjlltwtsszwswgssjnsjnnfqfzqqjzjfjmfmwfmfhfn ...\n"
]
}
],
"source": [
"in6 = parse(6)[0]"
]
@@ -456,9 +661,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 18,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.001 seconds for correct answer: 1,987'"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def first_marker(stream, n=4) -> int:\n",
" \"\"\"The number of characters read before the first start-of-packet marker is detected.\"\"\"\n",
@@ -478,9 +694,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 19,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.002 seconds for correct answer: 3,059'"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"answer(6.2, 3059, lambda: first_marker(in6, 14))"
]
@@ -503,9 +730,36 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 20,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Puzzle input ➜ 1087 lines:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"$ cd /\n",
"$ ls\n",
"dir bfbjzfd\n",
"dir mbc\n",
"dir psqmv\n",
"dir qqpgw\n",
"...\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Parsed representation ➜ 1087 lists:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"['$', 'cd', '/']\n",
"['$', 'ls']\n",
"['dir', 'bfbjzfd']\n",
"['dir', 'mbc']\n",
"['dir', 'psqmv']\n",
"['dir', 'qqpgw']\n",
"...\n"
]
}
],
"source": [
"in7 = parse(7, str.split)"
]
@@ -521,9 +775,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 21,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.001 seconds for correct answer: 1,232,307'"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def browse(transcript) -> Counter:\n",
" \"\"\"Return a Counter of {directory_name: total_size}, as revealed by the transcript of commands and output.\"\"\"\n",
@@ -555,9 +820,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 22,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.001 seconds for correct answer: 7,268,994'"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def free_up(transcript, available=70_000_000, needed=30_000_000) -> int:\n",
" \"\"\"What is the size of the smallest directory you can delete to free up enough space?\"\"\"\n",
@@ -579,9 +855,36 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 23,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Puzzle input ➜ 99 lines:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"102200120221123133322123221134224301040024344534431245323303212210030001244234132301200020310012011\n",
"210101220131232022104432220132221131234351145114524135253112332342312410211104233102330122201111010\n",
"002220112233222031400442434031011023425412431121343221233533224144034042201244323431032200232101012\n",
"200202231012120110032413231132224255311432523511252253221451514335154032332342133133133321000002220\n",
"021023013300203310410132030422351131224513211322513324212421215535543510221102312443303330132321201\n",
"001000330003220124130413311435314333354422521213321212242324211253514231442434324114124112323213001\n",
"...\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Parsed representation ➜ 99 tuples:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"(1, 0, 2, 2, 0, 0, 1, 2, 0, 2, 2, 1, 1, 2, 3, 1, 3, 3, 3, 2, 2, 1, 2, 3, 2, 2, 1, 1, 3, 4, 2, 2, ...\n",
"(2, 1, 0, 1, 0, 1, 2, 2, 0, 1, 3, 1, 2, 3, 2, 0, 2, 2, 1, 0, 4, 4, 3, 2, 2, 2, 0, 1, 3, 2, 2, 2, ...\n",
"(0, 0, 2, 2, 2, 0, 1, 1, 2, 2, 3, 3, 2, 2, 2, 0, 3, 1, 4, 0, 0, 4, 4, 2, 4, 3, 4, 0, 3, 1, 0, 1, ...\n",
"(2, 0, 0, 2, 0, 2, 2, 3, 1, 0, 1, 2, 1, 2, 0, 1, 1, 0, 0, 3, 2, 4, 1, 3, 2, 3, 1, 1, 3, 2, 2, 2, ...\n",
"(0, 2, 1, 0, 2, 3, 0, 1, 3, 3, 0, 0, 2, 0, 3, 3, 1, 0, 4, 1, 0, 1, 3, 2, 0, 3, 0, 4, 2, 2, 3, 5, ...\n",
"(0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 0, 3, 2, 2, 0, 1, 2, 4, 1, 3, 0, 4, 1, 3, 3, 1, 1, 4, 3, 5, 3, 1, ...\n",
"...\n"
]
}
],
"source": [
"in8 = Grid(parse(8, digits))"
]
@@ -597,9 +900,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 24,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.047 seconds for correct answer: 1,829'"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def visible_from_outside(grid) -> int:\n",
" \"\"\"How many points on grid are visible from the outside?\n",
@@ -631,9 +945,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 25,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.053 seconds for correct answer: 291,840'"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def scenic_score(loc, grid) -> int:\n",
" \"\"\"The product of the number of trees you can see in each of the 4 directions.\"\"\"\n",
@@ -668,9 +993,22 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 26,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 864x864 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"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",
@@ -688,9 +1026,36 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 27,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Puzzle input ➜ 2000 lines:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"L 1\n",
"R 1\n",
"U 1\n",
"R 1\n",
"L 1\n",
"U 2\n",
"...\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Parsed representation ➜ 2000 tuples:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"('L', 1)\n",
"('R', 1)\n",
"('U', 1)\n",
"('R', 1)\n",
"('L', 1)\n",
"('U', 2)\n",
"...\n"
]
}
],
"source": [
"in9 = parse(9, atoms)"
]
@@ -708,9 +1073,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 28,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.020 seconds for correct answer: 6,236'"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def move_rope(motions, start=(0, 4)) -> Set[Point]:\n",
" \"\"\"Move rope according to `motions`; return set of points visited by tail.\"\"\"\n",
@@ -748,9 +1124,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 29,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.112 seconds for correct answer: 2,449'"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def move_rope(motions, start=(0, 4), knots=2) -> Set[Point]:\n",
" deltas = dict(R=East, L=West, U=North, D=South)\n",
@@ -779,27 +1166,66 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 30,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAApoAAAKaCAYAAACeDPn/AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOy9T4gcR7bv/+0udRvuwjBzBdr17ZHsnTbWrjciB0keeIJ5i97L2CDvHlpdaMNvRoj5wQi8Et6NBl/wvjcX+m1s83LnnbzR8loW2hnEHfBi4LW6ut8i4nSePBkRGVmVWZVV9f1Ak6qszMiIyEz16W+cP1sXFxcghBBCCCGkb7aX3QFCCCGEELKe0NAkhBBCCCGDQEOTEEIIIYQMAg1NQgghhBAyCDQ0CSGEEELIINDQJIQQQgghg0BDkxBCCCGEDAINTUIIIYQQMgg0NAkhhBBCyCDQ0CSEEEIIIYNAQ5MQQgghhAwCDU1CCCGEEDIINDQJIYQQQsgg0NAkhBBCCCGDQEOTEEIIIYQMAg1NQgghhBAyCDQ0CSGEEELIINDQJIQQQgghg0BDkxBCCCGEDAINTUIIIYQQMgg0NAkhhBBCyCDQ0CSEEEIIIYNAQ5MQQgghhAwCDU1CCCGEEDIINDQJIYQQQsgg0NAkhBBCCCGDQEOTEEIIIYQMAg1NQgghhBAyCDQ0CSGEEELIINDQJIQQQgghg0BDkxBCCCGEDAINTUIIIYQQMgg0NAkhhBBCyCBcWXYHCCGrw/7RyQGAAkDpdxUA3gK4CqB8/fT+D0vpGCGEkFGydXFxsew+EEJWAG9kfg9gF8CZ330FwATAFMApgDs0NgkhhAhUNAkhDbRy+frp/R/858dwRuYEwJY/VNxvJv67AgANTUIIIQBoaBJCDEa5PN0/OnkE4BkqI3OKStHcQd3YfLvY3hJCCBkzXDonZMWwamNPbYmf5VsAhwDuojIqXwG4AWdQngP4FsAT38Rjc+x3AJ5w+ZwQQghAQ5OQlcKqjZjDJ9K0JYbiBM6Y3FafZSt8/vrp/eeJNuirSQghBADTGxGyahSojLpdAI+9sTdvW1BbMTJfoWlkTuGUTwCANybvwCmZcqz4ahJCCNlwaGgSslq8Rd0wvAvg+xmNzRJOfZya/aJKHqNuZJ77/aU+2Bub+lj6ahJCCAFAQ5OQVeMq6obhBC4gp+jakFEjz/3uc//5DoBf1bWmcL6ZsSXxq+bYq4FjCCGEbBiMOidktSjhVEVZ8j73P3v7RycPUQX0dEmg/jOAd769d/DBPPtHJ4CLLt+CMx5/BnBz/+ik0G17NXXPH3vh2yjnHyohhJBVh8FAhKwY3rB7AOAzuD8WJRrcBvAkg3ICCdj/A8A3xoD8P6hSGDXa9k1F2yCEELLZcOmckBXDG3Fv4Iw+eYd1LkvZRpfUAwnYJwDeGAOxQGXIhtp+kNEGIYSQDYZL54SsJjooCHBL1lvq8zkiS9iRlEShY+01tGo6BfAp6iUouWROCCGkBhVNQlYTG3zzX6gH9PwE4FFEXSxQNzK/Q3iJ3V7jWwBP/fH/G3UjM9YGIYSQDYaGJiGriU1z9APqy+g3ADyLpD2y5x5HDER73I8AHsGlVLqf2QYhhJANhkvnhKwmojaKongN9eTq26gSuh+jHo2+Z86NpSLS1ziHK035nm/bBiAxnREhhJAGNDQJWU1KuMjvHTjfyGMAt9Gs9PMxgD+gblhOzTGx5OpyDWnzOirVdAuVTygTtBNCCAnCpXNCVhCVbP3PcL6Rz+GWtV+h8tUE6sagbK/ABQ/BHxtUIyPlJaHOk+tMARzOUQqTEELImsI8moSsAYFI8i587g3Vrm2fokpr1Jq3kxBCyOZBQ5OQFcMbfgUqn8u3cP6Td5FnZIoSKf6V38EtvUerCam8m/fUec8B/E5ddwrgT6+f3v/rjEMjhBCyZtDQJGSFiOTAlGAdXb2nDa1G6nOjqqS6tviF3gFwE8Df1GFJdZQQQshmQR9NQlaEQDUfoB5lfg7gH6j7aIY4B3CCyp9TV/7ZRaSaUMAv9Ac4FVTn76SvJiGEkEsYdU7ICpBQMq2i+RuEa59rtlHlwbR/bCYjyL1xqdXOt6jn77wL4Pb+0Ql9NQkhhFDRJGRFKNCs5vM5gD/57beoG5/f+v3foalwnqOq6mPJzonpjd9DVNWD4Nt8Dy5/J5VNQgjZcKhoErIahKr5XPpC7h+dAC5fZu37/aOTl3D5NSXROvxW+2gK4qNZtnUmobBK+1Q2CSGEUNEkZEWwdcet6hj8XvlVfmu+/xp1tfMc3eqVF6gbma/QVDZ3EPH3JIQQshnQ0CRkNSgBnMEZhGdQqqNXF/f8/jMYVdIbjk/M+S8A/AwXPX4G4P8CeNJBfdT9mQJ46beSxmLq2y4D5xJCCNkQuHROyApjlrDPAPwdwDctBuMWgK/g3v/cc1Jt7QL4I6qgpHdwiumsbRJCCFkTaGgSshoUcO/rtt8+3j86OYYLxtH+l28AYP/o5As0E7rr8+H/fQHgTa5BqJLF7/l2bInLbf+T3SYhhJD1hYYmIatBCbckLn6R9+CCf6ao58F8H+EgnQtURqEEA22jw/J2QD09U9fVEe9cMieEEAKAhiYhK8Hrp/d/2D86uQOXsF2XmrRR4x8hnNB9yxx3AuBf4KLTc5XHwrT9HE5B1cpptIwlIYSQzYMlKAlZIVrSCgHANwAeqM+SuF0ncBcl8goSJScD134IlpskhBDSARqahKwYyk9SfC8/hlMszwH8BOAGKuPyJ7hKPtcA/OK3/0QVvCPJ34MR54Fr3UNlsP7p9dP7fx1mlIQQQtYBGpqErDABlVH7YgLNUpRW0ZR9DWWzpexlthJKCCFkc2EeTUJWG52oHagbmUA9UEi2VwD8b1RJ1idwxmQhJ3kj8zGa/p6igNLIJIQQ0gqDgQhZbXRpylwmAO6jSnck+94CQSVTq6Kn6JbYnRBCyAZDQ5OQ1UYUzS7G5jnqRiZQL2tZoL5c/h2AYzCinBBCSEdoaBKy2lhF0/pohpA8mkFF07Q5gUuBxOhyQgghnaGPJiGrjfbRnAL4L9R9NkOcw+XR/Mn/W/Zd9cvmh6bNq40WCCGEkAxoaBKy2pRw6uSZ3x6jrnCeB87ZhvPRlDRIsk+qCt1DXdF8axsghBBCcqChScgK4/0l7wD4s9/+iroaqVVL4RzADpo+modwvpkx301CCCGkE/TRJGTF8cbmDwCwf3RyE8a/EsAj1IN7pv6zIMFE19EMKqKiSQghZGZoaBKyXugodKl9/sxvY5WBXiFsZMJ/f7h/dCJtX9Yz998XYCQ6IYSQCKwMRMgakajmE6p1PgHwDk7xfIZw3sy2NjrVSyeEELJZ0EeTkDVC+Wx+h3p+TZ3GaALgP+D9On3qojsA/gTgcwD/n9+m2tjxP/LvYqgxEUIIWV2oaBKyhmRU93mE+lK43Za+qf+DKnDoXG21onkG4GsA31DVJIQQoqGhScia4o3NAmFjUi+V2yVybYx+BWdonsHl3pTSldrQ1AYsl9AJIYRcwmAgQtYUHY2u2T86+QKVkYnIdhcu3ZEYkhMAEtG+jer/DrucXoSuSQghZDOhjyYhm0cJpz6G8msKE7godW18foBK8Xznf3TOzneoltwJIYQQLp0Tson4ZfXHAO6iMh7/AeC3qJbCv1PfC+cAvgXwxH8uoPw6uWxOCCFEQ0OTkA0lkQpJ/C2fATgKnPq5j1QnhBBCktDQJGSDiSibrwB8CadS/gXtiiaVTEIIIUFoaBKy4USUzZSiyYTthBBCsqChSQhJKZs3EA4aPAew5X9E5TwGfTUJIYQoaGgSQgAA+0cnDwH8Te3SVYEA4ALOsAxh/TupcBJCCGF6I0LIpaJ5iCpdEVA3MqcA/kt9f45mOiTZ7gJ47NskhBCywVDRJGTDSUSfC7pS0DO4xOxicF4JHEtlkxBCCAAqmoQQFzmua6K/QqVWnsPl07zjUxrdAfBnAL/3P9+ZY1+hMjZ3fduEEEI2FJagJIS8RaVKbsMF9TyCUy7fAXgiqqQta7l/dHIM4A/q3B8AfOg/T3zbhBBCNhQamoSQq6gvef8Kp1wWaI8g1+eeAzjwW6kudHWwXhNCCBk9NDQJIVrRnAB4a5XLzHO3AVxHZWSegrXPCSFko6GPJiFEVEmguwqpzwUqVVT8OhkIRAghGwwNTUJICac+nvmfvQ6pieRcbaieQvl1EkII2VyY3ogQIimOHgD4FB3LSvpzC7hldFYGIoQQcgkNTUJWhIBBZ7dzGXj7RydfAPgLquXvP71+ev+vc3abEELIBsNgIEJWgERS9VqC9P2jk3n8IhtBQXN1mhBCyMZDQ5OQ1aBAZWQispXSj8eYTfG0aY6YmogQQshc0NAkZDUo4fwmdQUfHcx37vffhUugPoviSUWTEEJIrzDqnJAVwBuHdwD8CcDnAL5FPdL7J1TGJiJbUTxjEeVXUS8nSUWTEELIXFDRJGRF0EnU949OgKr04wT10o9AU/GU4+4BuB1RNt+qc7ZBRZMQQsicUNEkZDWxSdavmc//DSCUUmIbTtks9E6vch5i9sTthBBCSAMqmoSsJtaf8hfz+bcAttTxWuGs+V8GItobxxBCCCGzQEWTkNXEKpoHqPwrgWag0H8jrlYWqBuZcs5hhwpBhBBCSAMamoSsJiWq0o8TAB8g/j5vA/gN4mqlbguo1M+7AL6nsUkIIWRWWBmIkCWQUeWnNfelb+MxXIBPlz8apwCeA3gj7Zv+HMIZmawQRAghZC5oaBKyYAI+kaIgTgOfkzXH949OHgL4m9pl82fGOPXfN9oPtPn566f3n3cYIiGEEAKAwUCELIMCdZ9IHaRjP0vuyyfqXK16HqIyTM8BvIJLdXQAt5yuA4KEcwA7/rv3UK8mVIIVggghhPQEDU1CFk+JepUfIaRoSrWfwh9zJXCMzn15HS6f5hR1I1MLine truncated
"text/plain": [
"<Figure size 864x864 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"square_plot(move_rope(in9, knots=2), '.');"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 31,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 864x864 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"square_plot(move_rope(in9, knots=10), '.');"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 32,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 864x864 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"square_plot(move_rope(in9, knots=20), '.');"
]
@@ -822,9 +1248,36 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 33,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Puzzle input ➜ 145 lines:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"noop\n",
"noop\n",
"noop\n",
"addx 3\n",
"addx 7\n",
"noop\n",
"...\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"Parsed representation ➜ 145 tuples:\n",
"────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"('noop',)\n",
"('noop',)\n",
"('noop',)\n",
"('addx', 3)\n",
"('addx', 7)\n",
"('noop',)\n",
"...\n"
]
}
],
"source": [
"in10 = parse(10, atoms)"
]
@@ -838,9 +1291,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 34,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.000 seconds for correct answer: 12,560'"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def run(program) -> Iterable[Tuple[int, int]]:\n",
" \"\"\"Execute the program, oputputing (cycle_number, X_register_value) on each cycle.\n",
@@ -869,9 +1333,32 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 35,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"'0.011 seconds for correct answer: PLPAFBCL'"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
},
{
"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
"text/plain": [
"<Figure size 864x864 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"def render(program):\n",
" \"\"\"As the cycle number scans a 40-pixel wide CRT, turn on pixels\n",
@@ -897,19 +1384,42 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 36,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"{1.1: '0.000 seconds for correct answer: 70,116',\n",
" 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.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",
" 5.1: '0.000 seconds for correct answer: SHQWSRBDL',\n",
" 5.2: '0.000 seconds for correct answer: CDTQZHBRS',\n",
" 6.1: '0.001 seconds for correct answer: 1,987',\n",
" 6.2: '0.002 seconds for correct answer: 3,059',\n",
" 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.047 seconds for correct answer: 1,829',\n",
" 8.2: '0.053 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.011 seconds for correct answer: PLPAFBCL'}"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"answers"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {