|
14 | 14 | "trusted": true |
15 | 15 | }, |
16 | 16 | "cell_type": "code", |
17 | | - "source": "import os\nimport re\nimport string\n\nfrom collections import Counter, defaultdict\nfrom datetime import datetime\nfrom itertools import accumulate, chain, combinations, cycle, zip_longest\n\nimport numpy as np\nimport pandas as pd\nimport requests\n\nfrom scipy.spatial.distance import cdist", |
18 | | - "execution_count": 37, |
| 17 | + "source": "import os\nimport re\nimport string\n\nfrom collections import Counter, defaultdict\nfrom datetime import datetime\nfrom itertools import accumulate, chain, combinations, cycle, zip_longest\nimport operator as op\n\nimport networkx as nx\nimport numpy as np\nimport pandas as pd\nimport requests\n\nfrom scipy.spatial.distance import cdist\n\n%matplotlib inline", |
| 18 | + "execution_count": 47, |
19 | 19 | "outputs": [] |
20 | 20 | }, |
21 | 21 | { |
|
28 | 28 | }, |
29 | 29 | "cell_type": "code", |
30 | 30 | "source": "def input_for_day(day):\n file_name = f\"day{day:0>2}_input\"\n if os.path.exists(file_name):\n return os.path.abspath(file_name)\n with open(\"session\", \"r\") as session_file:\n response = requests.get(f\"https://adventofcode.com/2018/day/{day}/input\",\n cookies={\"session\": session_file.read()})\n with open(file_name, \"w\") as input_file:\n print(response.text.strip(), file=input_file)\n return os.path.abspath(file_name)", |
31 | | - "execution_count": 3, |
| 31 | + "execution_count": 2, |
32 | 32 | "outputs": [] |
33 | 33 | }, |
34 | 34 | { |
|
46 | 46 | }, |
47 | 47 | "cell_type": "code", |
48 | 48 | "source": "%time\nwith open(input_for_day(1), \"r\") as input_file:\n print(f'Answer: {sum(map(int, input_file))}')", |
49 | | - "execution_count": 4, |
| 49 | + "execution_count": 3, |
50 | 50 | "outputs": [ |
51 | 51 | { |
52 | 52 | "output_type": "stream", |
53 | | - "text": "CPU times: user 5 µs, sys: 2 µs, total: 7 µs\nWall time: 14.3 µs\nAnswer: 538\n", |
| 53 | + "text": "CPU times: user 2 µs, sys: 2 µs, total: 4 µs\nWall time: 9.06 µs\nAnswer: 538\n", |
54 | 54 | "name": "stdout" |
55 | 55 | } |
56 | 56 | ] |
|
70 | 70 | }, |
71 | 71 | "cell_type": "code", |
72 | 72 | "source": "%%time\nfreq_set = {0}\nwith open(input_for_day(1), \"r\") as input_file:\n for freq in accumulate(cycle(int(line) for line in input_file)):\n if freq in freq_set or freq_set.add(freq):\n print(f\"Answer: {freq}\")\n break", |
73 | | - "execution_count": 5, |
| 73 | + "execution_count": 4, |
74 | 74 | "outputs": [ |
75 | 75 | { |
76 | 76 | "output_type": "stream", |
77 | | - "text": "Answer: 77271\nCPU times: user 181 ms, sys: 287 ms, total: 468 ms\nWall time: 518 ms\n", |
| 77 | + "text": "Answer: 77271\nCPU times: user 48.2 ms, sys: 48.1 ms, total: 96.3 ms\nWall time: 120 ms\n", |
78 | 78 | "name": "stdout" |
79 | 79 | } |
80 | 80 | ] |
|
94 | 94 | }, |
95 | 95 | "cell_type": "code", |
96 | 96 | "source": "%%time\nwith open(input_for_day(2), \"r\") as input_file:\n counters = [Counter(n.strip()).values() for n in input_file]\nchecksum = sum(2 in c for c in counters) * sum(3 in c for c in counters)\nprint(f\"Answer: {checksum}\")", |
97 | | - "execution_count": 6, |
| 97 | + "execution_count": 5, |
98 | 98 | "outputs": [ |
99 | 99 | { |
100 | 100 | "output_type": "stream", |
101 | | - "text": "Answer: 5976\nCPU times: user 25.4 ms, sys: 1.95 ms, total: 27.4 ms\nWall time: 436 ms\n", |
| 101 | + "text": "Answer: 5976\nCPU times: user 3.79 ms, sys: 3.62 ms, total: 7.41 ms\nWall time: 185 ms\n", |
102 | 102 | "name": "stdout" |
103 | 103 | } |
104 | 104 | ] |
|
118 | 118 | }, |
119 | 119 | "cell_type": "code", |
120 | 120 | "source": "%%time\nwith open(input_for_day(2), \"r\") as input_file:\n counters = {x: Counter(x).values() for x in (n.strip() for n in input_file)}\nfor x, y in combinations((n for n, c in counters.items() if any(s in c for s in (2, 3))), 2):\n if sum(a != b for a, b in zip(x, y)) == 1:\n print(f\"Answer: {''.join(a for a, b in zip(x, y) if a == b)}\")\n break", |
121 | | - "execution_count": 7, |
| 121 | + "execution_count": 6, |
122 | 122 | "outputs": [ |
123 | 123 | { |
124 | 124 | "output_type": "stream", |
125 | | - "text": "Answer: xretqmmonskvzupalfiwhcfdb\nCPU times: user 59.2 ms, sys: 3.79 ms, total: 63 ms\nWall time: 123 ms\n", |
| 125 | + "text": "Answer: xretqmmonskvzupalfiwhcfdb\nCPU times: user 22.5 ms, sys: 2.29 ms, total: 24.7 ms\nWall time: 55.1 ms\n", |
126 | 126 | "name": "stdout" |
127 | 127 | } |
128 | 128 | ] |
|
138 | 138 | }, |
139 | 139 | "cell_type": "code", |
140 | 140 | "source": "%%time\nexpr = re.compile(r\"#(\\d+)\\s@\\s(\\d+),(\\d+):\\s(\\d+)x(\\d+)\")\nfabric = np.zeros((1000, 1000), dtype=np.uint32)\nwith open(input_for_day(3), \"r\") as input_file:\n for claim in input_file:\n _, x, y, w, h = map(int, expr.match(claim).groups())\n fabric[y:y+h, x:x+w] += 1\n print(f\"Answer: {np.sum(fabric > 1)}\")", |
141 | | - "execution_count": 8, |
| 141 | + "execution_count": 7, |
142 | 142 | "outputs": [ |
143 | 143 | { |
144 | 144 | "output_type": "stream", |
145 | | - "text": "Answer: 117948\nCPU times: user 80.5 ms, sys: 158 ms, total: 239 ms\nWall time: 392 ms\n", |
| 145 | + "text": "Answer: 117948\nCPU times: user 30.8 ms, sys: 502 µs, total: 31.3 ms\nWall time: 309 ms\n", |
146 | 146 | "name": "stdout" |
147 | 147 | } |
148 | 148 | ] |
|
158 | 158 | }, |
159 | 159 | "cell_type": "code", |
160 | 160 | "source": "%%time\nexpr = re.compile(r\"#(\\d+)\\s@\\s(\\d+),(\\d+):\\s(\\d+)x(\\d+)\")\nfabric = np.zeros((1000, 1000), dtype=np.uint32)\nwith open(input_for_day(3), \"r\") as input_file:\n claims = [list(map(int, expr.match(claim).groups())) for claim in input_file]\nfor claim in claims:\n _, x, y, w, h = claim\n fabric[y:y+h, x:x+w] += 1\nfor claim in claims:\n claim_id, x, y, w, h = claim\n if np.all(fabric[y:y+h, x:x+w] == 1):\n print(f\"Answer: {claim_id}\")\n break", |
161 | | - "execution_count": 9, |
| 161 | + "execution_count": 8, |
162 | 162 | "outputs": [ |
163 | 163 | { |
164 | 164 | "output_type": "stream", |
165 | | - "text": "Answer: 567\nCPU times: user 77.3 ms, sys: 68.9 ms, total: 146 ms\nWall time: 199 ms\n", |
| 165 | + "text": "Answer: 567\nCPU times: user 25 ms, sys: 4.89 ms, total: 29.9 ms\nWall time: 66.1 ms\n", |
166 | 166 | "name": "stdout" |
167 | 167 | } |
168 | 168 | ] |
|
178 | 178 | }, |
179 | 179 | "cell_type": "code", |
180 | 180 | "source": "%%time\nentry_expr = re.compile(r\"\\[(.+)\\]\\s(.*)\")\nguard_expr = re.compile(\"Guard\\s#(\\d+)\")\n\nguards = defaultdict(Counter)\nwith open(input_for_day(4), \"r\") as input_file:\n lines = (entry_expr.match(entry).groups() for entry in sorted(input_file))\nfor timestamp, event in ((datetime.strptime(t, \"%Y-%m-%d %H:%M\"), e) for t, e in lines):\n if event.startswith(\"Guard\"):\n guard = int(guard_expr.match(event).group(1))\n elif event.startswith(\"falls\"):\n start = timestamp\n elif event.startswith(\"wakes\"):\n duration = int((timestamp - start).total_seconds()) // 60\n guards[guard].update(Counter(start.minute + i for i in range(duration)))\n\n_, guard = max((sum(c.values()), g) for g, c in guards.items())\n\nprint(f\"Answer: {guard * guards[guard].most_common()[0][0]}\")", |
181 | | - "execution_count": 10, |
| 181 | + "execution_count": 9, |
182 | 182 | "outputs": [ |
183 | 183 | { |
184 | 184 | "output_type": "stream", |
185 | | - "text": "Answer: 4716\nCPU times: user 118 ms, sys: 1.6 ms, total: 120 ms\nWall time: 349 ms\n", |
| 185 | + "text": "Answer: 4716\nCPU times: user 31.4 ms, sys: 2.52 ms, total: 33.9 ms\nWall time: 89.2 ms\n", |
186 | 186 | "name": "stdout" |
187 | 187 | } |
188 | 188 | ] |
|
198 | 198 | }, |
199 | 199 | "cell_type": "code", |
200 | 200 | "source": "%%time\nentry_expr = re.compile(r\"\\[(.+)\\]\\s(.*)\")\nguard_expr = re.compile(\"Guard\\s#(\\d+)\")\n\nguards = defaultdict(Counter)\nwith open(input_for_day(4), \"r\") as input_file:\n lines = (entry_expr.match(entry).groups() for entry in sorted(input_file))\nfor timestamp, event in ((datetime.strptime(t, \"%Y-%m-%d %H:%M\"), e) for t, e in lines):\n if event.startswith(\"Guard\"):\n guard = int(guard_expr.match(event).group(1))\n elif event.startswith(\"falls\"):\n start = timestamp\n elif event.startswith(\"wakes\"):\n duration = int((timestamp - start).total_seconds()) // 60\n guards[guard].update(Counter(start.minute + i for i in range(duration)))\n\n(_, minute), guard = max((c.most_common()[0][::-1], g) for g, c in guards.items())\n\nprint(f\"Answer: {guard * minute}\")", |
201 | | - "execution_count": 11, |
| 201 | + "execution_count": 10, |
202 | 202 | "outputs": [ |
203 | 203 | { |
204 | 204 | "output_type": "stream", |
205 | | - "text": "Answer: 117061\nCPU times: user 111 ms, sys: 0 ns, total: 111 ms\nWall time: 210 ms\n", |
| 205 | + "text": "Answer: 117061\nCPU times: user 53.2 ms, sys: 2.58 ms, total: 55.7 ms\nWall time: 90.7 ms\n", |
206 | 206 | "name": "stdout" |
207 | 207 | } |
208 | 208 | ] |
|
218 | 218 | }, |
219 | 219 | "cell_type": "code", |
220 | 220 | "source": "%%time\ndef collapse(s):\n p = [\"_\"]\n for u in s:\n v = p[-1]\n p.pop() if v != u and v.lower() == u.lower() else p.append(u)\n \n return len(p) - 1\n\nwith open(input_for_day(5), \"r\") as input_file:\n print(f\"Answer: {collapse(input_file.read().strip())}\")", |
221 | | - "execution_count": 12, |
| 221 | + "execution_count": 11, |
222 | 222 | "outputs": [ |
223 | 223 | { |
224 | 224 | "output_type": "stream", |
225 | | - "text": "Answer: 11252\nCPU times: user 67.2 ms, sys: 2.33 ms, total: 69.5 ms\nWall time: 558 ms\n", |
| 225 | + "text": "Answer: 11252\nCPU times: user 21.9 ms, sys: 1.51 ms, total: 23.4 ms\nWall time: 392 ms\n", |
226 | 226 | "name": "stdout" |
227 | 227 | } |
228 | 228 | ] |
|
238 | 238 | }, |
239 | 239 | "cell_type": "code", |
240 | 240 | "source": "%%time\ndef collapse(s):\n p = [\"_\"]\n for u in s:\n v = p[-1]\n p.pop() if v != u and v.lower() == u.lower() else p.append(u)\n \n return len(p) - 1\n\nwith open(input_for_day(5), \"r\") as input_file:\n data = input_file.read().strip()\nmin_length = min(collapse(s) for s in (data.replace(l, \"\").replace(l.swapcase(), \"\") for l in string.ascii_lowercase))\nprint(f\"Answer: {min_length}\")", |
241 | | - "execution_count": 13, |
| 241 | + "execution_count": 12, |
242 | 242 | "outputs": [ |
243 | 243 | { |
244 | 244 | "output_type": "stream", |
245 | | - "text": "Answer: 6118\nCPU times: user 1.63 s, sys: 0 ns, total: 1.63 s\nWall time: 1.68 s\n", |
| 245 | + "text": "Answer: 6118\nCPU times: user 459 ms, sys: 4.78 ms, total: 464 ms\nWall time: 493 ms\n", |
246 | 246 | "name": "stdout" |
247 | 247 | } |
248 | 248 | ] |
|
257 | 257 | "trusted": true |
258 | 258 | }, |
259 | 259 | "cell_type": "code", |
260 | | - "source": "%%time\nwith open(input_for_day(6), \"r\") as input_file:\n points = np.fromiter(chain.from_iterable(map(int, l.strip().split(\",\")) for l in input_file), np.uint).reshape(50, 2)\n\n# Boundaries\ntl = np.min(points, axis=0)\nbr = np.max(points, axis=0) + 1\n\n# Index grid\nxx, yy = np.mgrid[tl[0]:br[0], tl[1]:br[1]]\npositions = np.vstack([xx.ravel(), yy.ravel()]).T\n\n# Manhatten distances\ndists = cdist(positions, points, metric='cityblock')\nmin_dists = np.min(dists, axis=1)\n\n# Mapping to pointts\nindex_array = (min_dists[..., np.newaxis] == dists)\n\n# Non ambigious distances\nnon_ambigious_index = (np.sum(index_array, axis=1) == 1)\nindex_array = index_array[non_ambigious_index]\n\n# Borders to filter infinit regions\nborder_index = np.any(np.vstack([tl, br-1])[:,np.newaxis] == positions, axis=(0, 2))\nborder_index = border_index[non_ambigious_index]\nborder_index = np.any(index_array[border_index], axis=0)\n\n# Compute arrea for all points\narea = np.sum(index_array, axis=0)\n\n# Remove points that areas touch the borders\narea[border_ids] = -1\n\nprint(f\"Answer: {np.max(area)}\")", |
261 | | - "execution_count": 179, |
| 260 | + "source": "%%time\nwith open(input_for_day(6), \"r\") as input_file:\n points = np.fromiter(chain.from_iterable(map(int, l.strip().split(\",\")) for l in input_file), np.uint).reshape(50, 2)\n\n# Boundaries\ntl = np.min(points, axis=0)\nbr = np.max(points, axis=0) + 1\n\n# Index grid\nxx, yy = np.mgrid[tl[0]:br[0], tl[1]:br[1]]\npositions = np.vstack([xx.ravel(), yy.ravel()]).T\n\n# Manhatten distances\ndists = cdist(positions, points, metric='cityblock')\nmin_dists = np.min(dists, axis=1)\n\n# Mapping to pointts\nindex_array = (min_dists[..., np.newaxis] == dists)\n\n# Non ambigious distances\nnon_ambigious_index = (np.sum(index_array, axis=1) == 1)\nindex_array = index_array[non_ambigious_index]\n\n# Borders to filter infinit regions\nborder_index = np.any(np.vstack([tl, br-1])[:,np.newaxis] == positions, axis=(0, 2))\nborder_index = border_index[non_ambigious_index]\nborder_index = np.any(index_array[border_index], axis=0)\n\n# Compute arrea for all points\narea = np.sum(index_array, axis=0)\n\n# Remove points that areas touch the borders\narea[border_index] = -1\n\nprint(f\"Answer: {np.max(area)}\")", |
| 261 | + "execution_count": 15, |
262 | 262 | "outputs": [ |
263 | 263 | { |
264 | 264 | "output_type": "stream", |
265 | | - "text": "Answer: 4754\nCPU times: user 171 ms, sys: 62 ms, total: 233 ms\nWall time: 623 ms\n", |
| 265 | + "text": "Answer: 4754\nCPU times: user 47.5 ms, sys: 465 ms, total: 512 ms\nWall time: 568 ms\n", |
266 | 266 | "name": "stdout" |
267 | 267 | } |
268 | 268 | ] |
|
277 | 277 | "trusted": true |
278 | 278 | }, |
279 | 279 | "cell_type": "code", |
280 | | - "source": "print(f\"Answer: {np.sum(np.sum(dists, axis=1) < 10000)}\")", |
281 | | - "execution_count": 176, |
| 280 | + "source": "%%time\nwith open(input_for_day(6), \"r\") as input_file:\n points = np.fromiter(chain.from_iterable(map(int, l.strip().split(\",\")) for l in input_file), np.uint).reshape(50, 2)\n\n# Boundaries\ntl = np.min(points, axis=0)\nbr = np.max(points, axis=0) + 1\n\n# Index grid\nxx, yy = np.mgrid[tl[0]:br[0], tl[1]:br[1]]\npositions = np.vstack([xx.ravel(), yy.ravel()]).T\n\n# Manhatten distances\ndists = cdist(positions, points, metric='cityblock')\n\nprint(f\"Answer: {np.sum(np.sum(dists, axis=1) < 10000)}\")", |
| 281 | + "execution_count": 17, |
282 | 282 | "outputs": [ |
283 | 283 | { |
284 | 284 | "output_type": "stream", |
285 | | - "text": "Answer: 42344\n", |
| 285 | + "text": "Answer: 42344\nCPU times: user 42.2 ms, sys: 62.7 ms, total: 105 ms\nWall time: 217 ms\n", |
286 | 286 | "name": "stdout" |
287 | 287 | } |
288 | 288 | ] |
| 289 | + }, |
| 290 | + { |
| 291 | + "metadata": {}, |
| 292 | + "cell_type": "markdown", |
| 293 | + "source": "## Day 7\n### Part One\nIn what order should the steps in your instructions be completed?" |
| 294 | + }, |
| 295 | + { |
| 296 | + "metadata": { |
| 297 | + "trusted": true |
| 298 | + }, |
| 299 | + "cell_type": "code", |
| 300 | + "source": "%%time\nwith open(input_for_day(7), \"r\") as input_file:\n edges = [re.findall(\"\\s(\\w)\\s\", edge) for edge in input_file]\nvertices = set(chain.from_iterable(edges))\n\nG = nx.DiGraph()\nG.add_nodes_from(vertices)\nG.add_edges_from(edges)\n\nresult = []\nwhile G.nodes:\n n = min(G.in_degree(G.nodes), key=lambda x: (x[1],x[0]))[0]\n G.remove_node(n)\n result.append(n)\n\nprint(f\"Answer: {''.join(result)}\")", |
| 301 | + "execution_count": 83, |
| 302 | + "outputs": [ |
| 303 | + { |
| 304 | + "output_type": "stream", |
| 305 | + "text": "Answer: JNOIKSYABEQRUVWXGTZFDMHLPC\nCPU times: user 3.17 ms, sys: 937 µs, total: 4.11 ms\nWall time: 48.9 ms\n", |
| 306 | + "name": "stdout" |
| 307 | + } |
| 308 | + ] |
| 309 | + }, |
| 310 | + { |
| 311 | + "metadata": {}, |
| 312 | + "cell_type": "markdown", |
| 313 | + "source": "### Part Two\nWith 5 workers and the 60+ second step durations described above, how long will it take to complete all of the steps?" |
| 314 | + }, |
| 315 | + { |
| 316 | + "metadata": { |
| 317 | + "trusted": true |
| 318 | + }, |
| 319 | + "cell_type": "code", |
| 320 | + "source": "with open(input_for_day(7), \"r\") as input_file:\n edges = [re.findall(\"\\s(\\w)\\s\", edge) for edge in input_file]\nvertices = set(chain.from_iterable(edges))\n\nG = nx.DiGraph()\nG.add_nodes_from((v, {\"steptime\": ord(v) - 4}) for v in vertices)\nG.add_edges_from(edges)\nG.nodes(\"steptime\")", |
| 321 | + "execution_count": 84, |
| 322 | + "outputs": [ |
| 323 | + { |
| 324 | + "output_type": "execute_result", |
| 325 | + "execution_count": 84, |
| 326 | + "data": { |
| 327 | + "text/plain": "NodeDataView({'U': 81, 'X': 84, 'S': 79, 'W': 83, 'E': 65, 'D': 64, 'B': 62, 'N': 74, 'C': 63, 'R': 78, 'V': 82, 'Q': 77, 'I': 69, 'Z': 86, 'J': 70, 'O': 75, 'M': 73, 'H': 68, 'F': 66, 'L': 72, 'T': 80, 'G': 67, 'P': 76, 'K': 71, 'A': 61, 'Y': 85}, data='steptime')" |
| 328 | + }, |
| 329 | + "metadata": {} |
| 330 | + } |
| 331 | + ] |
| 332 | + }, |
| 333 | + { |
| 334 | + "metadata": { |
| 335 | + "trusted": true |
| 336 | + }, |
| 337 | + "cell_type": "code", |
| 338 | + "source": "", |
| 339 | + "execution_count": null, |
| 340 | + "outputs": [] |
289 | 341 | } |
290 | 342 | ], |
291 | 343 | "metadata": { |
|
0 commit comments