From e9bd759dba8350b0b9b80ba250aab8bada874d29 Mon Sep 17 00:00:00 2001 From: felixm Date: Thu, 21 Nov 2024 08:43:15 -0500 Subject: [PATCH] Solve 2021 day 7-11 --- 2021/d10.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2021/d11.py | 37 ++++++++++++++++++++++++++++++ 2021/d7.py | 20 +++++++++++++++++ 2021/d8.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2021/d9.py | 47 ++++++++++++++++++++++++++++++++++++++ README.md | 19 ++++++++++------ 6 files changed, 244 insertions(+), 7 deletions(-) create mode 100644 2021/d10.py create mode 100644 2021/d11.py create mode 100644 2021/d7.py create mode 100644 2021/d8.py create mode 100644 2021/d9.py diff --git a/2021/d10.py b/2021/d10.py new file mode 100644 index 0000000..bc8621d --- /dev/null +++ b/2021/d10.py @@ -0,0 +1,63 @@ +from lib import get_data + +data = get_data(__file__).strip() + +OPEN = "([{<" +CLOSE = ")]}>" + + +def part1(line): + score = { + ")": 3, + "]": 57, + "}": 1197, + ">": 25137, + } + stack = [] + for c in line: + if c in OPEN: + stack.append(OPEN.index(c)) + elif c in CLOSE: + ci = CLOSE.index(c) + if stack and stack[-1] == ci: + stack.pop() + continue + else: + return score[c] + else: + assert False + return 0 + + +def part2(line): + stack = [] + for c in line: + if c in OPEN: + stack.append(OPEN.index(c)) + elif c in CLOSE: + ci = CLOSE.index(c) + if stack and stack[-1] == ci: + stack.pop() + continue + else: + assert False + else: + assert False + score = 0 + for v in reversed(stack): + score *= 5 + score += v + 1 + return score + + +s1 = 0 +s2s = [] +for line in data.splitlines(): + s = part1(line) + if s == 0: + s2s.append(part2(line)) + s1 += s + +print(s1) +s2 = sorted(s2s)[len(s2s) // 2] +print(s2) diff --git a/2021/d11.py b/2021/d11.py new file mode 100644 index 0000000..27dc146 --- /dev/null +++ b/2021/d11.py @@ -0,0 +1,37 @@ +from lib import get_data +from lib import Grid2D + +data = get_data(__file__).strip() +g = Grid2D(data) + +flashes_100 = 0 +all_flash_round = None +for i in range(10**9): + for row in range(g.n_rows): + for col in range(g.n_cols): + g[(row, col)] = str(int(g[(row, col)]) + 1) + + has_flashed = set() + more_flashes = True + while more_flashes: + more_flashes = False + for row in range(g.n_rows): + for col in range(g.n_cols): + level = int(g[(row, col)]) + if level > 9 and (row, col) not in has_flashed: + more_flashes = True + for nb in g.neighbors_adj((row, col)): + g[nb] = str(int(g[nb]) + 1) + has_flashed.add((row, col)) + for oct in has_flashed: + g[oct] = "0" + + if i < 100: + flashes_100 += len(has_flashed) + + if len(has_flashed) == g.n_rows * g.n_cols: + all_flash_round = i + 1 + break + +print(flashes_100) +print(all_flash_round) diff --git a/2021/d7.py b/2021/d7.py new file mode 100644 index 0000000..e1718b4 --- /dev/null +++ b/2021/d7.py @@ -0,0 +1,20 @@ +from lib import get_data +from lib import ints + +data = get_data(__file__).strip() +xs = ints(data) + + +def d(t, x): + n = abs(t - x) + return n * (n + 1) // 2 + + +s_min_1 = 10**16 +s_min_2 = 10**16 +for t in range(min(xs), max(xs) + 1): + s_min_1 = min(s_min_1, sum(abs(t - x) for x in xs)) + s_min_2 = min(s_min_2, sum(d(t, x) for x in xs)) + +print(s_min_1) +print(s_min_2) diff --git a/2021/d8.py b/2021/d8.py new file mode 100644 index 0000000..5a80281 --- /dev/null +++ b/2021/d8.py @@ -0,0 +1,65 @@ +from lib import get_data +from itertools import permutations + +data = get_data(__file__).strip() + +code_to_num = { + "cf": 1, + "acf": 7, + "bcdf": 4, + "acdeg": 2, + "acdfg": 3, + "abdfg": 5, + "abcefg": 0, + "abdefg": 6, + "abcdfg": 9, + "abcdefg": 8, +} + + +def translate(inn, mapping): + out = "" + for c in inn: + out += mapping[c] + return "".join(sorted(out)) + + +def decode(inn, out): + s = "abcdefg" + m = None + for p in permutations(s): + m = {k: v for k, v in zip(p, s)} + all = set(code_to_num.keys()) + for in_code in inn: + out_code = translate(in_code, m) + if out_code in all: + all.remove(out_code) + + if len(all) == 0: + break + else: + m = None + + assert m is not None + + o = 0 + d = 1000 + for out_code in out: + out_code = translate(out_code, m) + v = code_to_num[out_code] + o += d * v + d //= 10 + return o + + +s1 = 0 +s2 = 0 +for line in data.splitlines(): + inn, out = line.strip().split(" | ") + inn = inn.split() + out = out.split() + s1 += sum(1 for v in out if len(v) in [2, 3, 4, 7]) + s2 += decode(inn, out) + +print(s1) +print(s2) diff --git a/2021/d9.py b/2021/d9.py new file mode 100644 index 0000000..85b527d --- /dev/null +++ b/2021/d9.py @@ -0,0 +1,47 @@ +from lib import get_data, Grid2D +from collections import deque + +data = get_data(__file__).strip() +g = Grid2D(data) + +s = 0 +low_points = [] +for row in range(g.n_rows): + for col in range(g.n_cols): + h = int(g[(row, col)]) + for nb in g.neighbors_ort((row, col)): + if int(g[nb]) <= h: + break + else: + low_points.append((row, col)) + s += 1 + h + +print(s) + +basins = [] +for row, col in low_points: + start = None + visited = set() + queue = deque([(row, col)]) + + while queue: + vertex = queue.popleft() + if vertex in visited: + continue + visited.add(vertex) + + neighbors = [] + for neighbor in g.neighbors_ort(vertex): + if neighbor in visited: + continue + + neighbor_height = int(g[neighbor]) + if neighbor_height < 9: + queue.append(neighbor) + + basins.append(len(visited)) + +s = 1 +for x in sorted(basins)[-3:]: + s *= x +print(s) diff --git a/README.md b/README.md index 4c26602..71ee3bb 100644 --- a/README.md +++ b/README.md @@ -172,13 +172,18 @@ Solutions and utility script for Advent of Code challenges in Python. ## AoC 2021 -- Day 1: 4:01 (Haha. Why am I so bad?!?!) -- Day 2: 6:36 (Okay. I might as well stop doing these.) -- Day 3: 23:46 (How long can I take when I try to take long?) -- Day 4: 22:18 (No way. Such stupid bugs.) -- Day 5: 13:30 (Decent, but obviously too slow.) -- Day 6: 16:33 (Right idea quickly but then struggled to implement.) -- Day 7: +- Day 1: 4:01 (Haha. Why am I so bad?!?!) +- Day 2: 6:36 (Okay. I might as well stop doing these.) +- Day 3: 23:46 (How long can I take when I try to take long?) +- Day 4: 22:18 (No way. Such stupid bugs.) +- Day 5: 13:30 (Decent, but obviously too slow.) +- Day 6: 16:33 (Right idea quickly but then struggled to implement.) +- Day 7: 6:12 (Decent, but too slow again, obviously. Maybe fast enough for part 1.) +- Day 8: 72:00 (Yeah, that was too much of a struggle.) +- Day 9: 8:07 (37th okay, okay) +- Day 10: 15:50 (I was pretty happy with that but double the 100th place.) +- Day 11: 11:43 (Could have been much faster here.) +- Day 12: ## AoC 2022