From 6b733982f9f240c1c97f1fa705bfbe4cd93c640e Mon Sep 17 00:00:00 2001 From: mhsn Date: Fri, 12 Sep 2025 20:20:58 +0100 Subject: simplify python file structure --- 2024/01/python.py | 14 ++++++++ 2024/01/python/main.py | 12 ------- 2024/01/python/pyproject.toml | 6 ---- 2024/02/python.py | 24 +++++++++++++ 2024/02/python/main.py | 22 ------------ 2024/02/python/pyproject.toml | 6 ---- 2024/03/python.py | 23 ++++++++++++ 2024/03/python/main.py | 21 ----------- 2024/03/python/pyproject.toml | 6 ---- 2024/04/python.py | 29 +++++++++++++++ 2024/04/python/main.py | 27 -------------- 2024/04/python/pyproject.toml | 6 ---- 2024/05/python.py | 30 ++++++++++++++++ 2024/05/python/main.py | 28 --------------- 2024/05/python/pyproject.toml | 6 ---- 2024/06/python.py | 57 +++++++++++++++++++++++++++++ 2024/06/python/main.py | 55 ---------------------------- 2024/06/python/pyproject.toml | 6 ---- 2024/07/python.py | 37 +++++++++++++++++++ 2024/07/python/main.py | 35 ------------------ 2024/07/python/pyproject.toml | 6 ---- 2024/08/python.py | 51 ++++++++++++++++++++++++++ 2024/08/python/main.py | 49 ------------------------- 2024/08/python/pyproject.toml | 6 ---- 2024/09/python.py | 62 ++++++++++++++++++++++++++++++++ 2024/09/python/main.py | 60 ------------------------------- 2024/09/python/pyproject.toml | 6 ---- 2024/10/python.py | 43 ++++++++++++++++++++++ 2024/10/python/main.py | 41 --------------------- 2024/10/python/pyproject.toml | 6 ---- 2024/11/python.py | 30 ++++++++++++++++ 2024/11/python/main.py | 28 --------------- 2024/11/python/pyproject.toml | 6 ---- 2024/12/python.py | 49 +++++++++++++++++++++++++ 2024/12/python/main.py | 47 ------------------------ 2024/12/python/pyproject.toml | 6 ---- 2024/13/python.py | 40 +++++++++++++++++++++ 2024/13/python/main.py | 38 -------------------- 2024/13/python/pyproject.toml | 6 ---- 2024/14/python.py | 64 +++++++++++++++++++++++++++++++++ 2024/14/python/main.py | 62 -------------------------------- 2024/14/python/pyproject.toml | 6 ---- 2024/15/python.py | 83 +++++++++++++++++++++++++++++++++++++++++++ 2024/15/python/main.py | 81 ----------------------------------------- 2024/15/python/pyproject.toml | 6 ---- 2024/16/python.py | 31 ++++++++++++++++ 2024/16/python/main.py | 29 --------------- 2024/16/python/pyproject.toml | 6 ---- 2024/17/python.py | 68 +++++++++++++++++++++++++++++++++++ 2024/17/python/main.py | 66 ---------------------------------- 2024/17/python/pyproject.toml | 6 ---- 2024/18/python.py | 47 ++++++++++++++++++++++++ 2024/18/python/main.py | 45 ----------------------- 2024/18/python/pyproject.toml | 6 ---- 2024/19/python.py | 42 ++++++++++++++++++++++ 2024/19/python/main.py | 40 --------------------- 2024/19/python/pyproject.toml | 6 ---- 2024/20/python.py | 40 +++++++++++++++++++++ 2024/20/python/main.py | 38 -------------------- 2024/20/python/pyproject.toml | 6 ---- 2024/21/python.py | 42 ++++++++++++++++++++++ 2024/22/python.py | 59 ++++++++++++++++++++++++++++++ 2024/22/python/main.py | 57 ----------------------------- 2024/22/python/pyproject.toml | 6 ---- 64 files changed, 965 insertions(+), 1007 deletions(-) create mode 100755 2024/01/python.py delete mode 100644 2024/01/python/main.py delete mode 100644 2024/01/python/pyproject.toml create mode 100755 2024/02/python.py delete mode 100644 2024/02/python/main.py delete mode 100644 2024/02/python/pyproject.toml create mode 100755 2024/03/python.py delete mode 100644 2024/03/python/main.py delete mode 100644 2024/03/python/pyproject.toml create mode 100755 2024/04/python.py delete mode 100644 2024/04/python/main.py delete mode 100644 2024/04/python/pyproject.toml create mode 100755 2024/05/python.py delete mode 100644 2024/05/python/main.py delete mode 100644 2024/05/python/pyproject.toml create mode 100755 2024/06/python.py delete mode 100644 2024/06/python/main.py delete mode 100644 2024/06/python/pyproject.toml create mode 100755 2024/07/python.py delete mode 100644 2024/07/python/main.py delete mode 100644 2024/07/python/pyproject.toml create mode 100755 2024/08/python.py delete mode 100644 2024/08/python/main.py delete mode 100644 2024/08/python/pyproject.toml create mode 100755 2024/09/python.py delete mode 100644 2024/09/python/main.py delete mode 100644 2024/09/python/pyproject.toml create mode 100755 2024/10/python.py delete mode 100644 2024/10/python/main.py delete mode 100644 2024/10/python/pyproject.toml create mode 100755 2024/11/python.py delete mode 100644 2024/11/python/main.py delete mode 100644 2024/11/python/pyproject.toml create mode 100755 2024/12/python.py delete mode 100644 2024/12/python/main.py delete mode 100644 2024/12/python/pyproject.toml create mode 100755 2024/13/python.py delete mode 100644 2024/13/python/main.py delete mode 100644 2024/13/python/pyproject.toml create mode 100755 2024/14/python.py delete mode 100644 2024/14/python/main.py delete mode 100644 2024/14/python/pyproject.toml create mode 100755 2024/15/python.py delete mode 100644 2024/15/python/main.py delete mode 100644 2024/15/python/pyproject.toml create mode 100755 2024/16/python.py delete mode 100644 2024/16/python/main.py delete mode 100644 2024/16/python/pyproject.toml create mode 100755 2024/17/python.py delete mode 100644 2024/17/python/main.py delete mode 100644 2024/17/python/pyproject.toml create mode 100755 2024/18/python.py delete mode 100644 2024/18/python/main.py delete mode 100644 2024/18/python/pyproject.toml create mode 100755 2024/19/python.py delete mode 100644 2024/19/python/main.py delete mode 100644 2024/19/python/pyproject.toml create mode 100755 2024/20/python.py delete mode 100644 2024/20/python/main.py delete mode 100644 2024/20/python/pyproject.toml create mode 100755 2024/21/python.py create mode 100755 2024/22/python.py delete mode 100644 2024/22/python/main.py delete mode 100644 2024/22/python/pyproject.toml (limited to '2024') diff --git a/2024/01/python.py b/2024/01/python.py new file mode 100755 index 0000000..425f6c7 --- /dev/null +++ b/2024/01/python.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 + +from collections import Counter +from fileinput import input + +L, R = zip(*[[int(n) for n in s.split()] for s in input()]) + +silver = sum(abs(left - right) for left, right in zip(sorted(L), sorted(R))) + +L, R = Counter(L), Counter(R) +gold = sum(n * L[n] * R[n] for n in list(L & R)) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/01/python/main.py b/2024/01/python/main.py deleted file mode 100644 index f920d5d..0000000 --- a/2024/01/python/main.py +++ /dev/null @@ -1,12 +0,0 @@ -from collections import Counter -from fileinput import input - -L, R = zip(*[[int(n) for n in s.split()] for s in input()]) - -silver = sum(abs(left - right) for left, right in zip(sorted(L), sorted(R))) - -L, R = Counter(L), Counter(R) -gold = sum(n * L[n] * R[n] for n in list(L & R)) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/01/python/pyproject.toml b/2024/01/python/pyproject.toml deleted file mode 100644 index ed9dd6f..0000000 --- a/2024/01/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-01" -version = "0.1.0" -description = "advent of code 2024-01" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/02/python.py b/2024/02/python.py new file mode 100755 index 0000000..f2c807d --- /dev/null +++ b/2024/02/python.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +from fileinput import input + +reports = [[int(level) for level in report.split()] for report in input()] + + +def incr(xs): + return all(x < y and y - x <= 3 for x, y in zip(xs, xs[1:])) + + +def safe(xs): + return incr(xs) or incr(xs[::-1]) + + +def drops(xs): + return (xs[:idx] + xs[idx + 1 :] for idx, _ in enumerate(xs)) + + +silver = sum(safe(rep) for rep in reports) +gold = sum(any(safe(mod) for mod in drops(rep)) for rep in reports) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/02/python/main.py b/2024/02/python/main.py deleted file mode 100644 index b4c8c9a..0000000 --- a/2024/02/python/main.py +++ /dev/null @@ -1,22 +0,0 @@ -from fileinput import input - -reports = [[int(level) for level in report.split()] for report in input()] - - -def incr(xs): - return all(x < y and y - x <= 3 for x, y in zip(xs, xs[1:])) - - -def safe(xs): - return incr(xs) or incr(xs[::-1]) - - -def drops(xs): - return (xs[:idx] + xs[idx + 1 :] for idx, _ in enumerate(xs)) - - -silver = sum(safe(rep) for rep in reports) -gold = sum(any(safe(mod) for mod in drops(rep)) for rep in reports) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/02/python/pyproject.toml b/2024/02/python/pyproject.toml deleted file mode 100644 index 7344524..0000000 --- a/2024/02/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-02" -version = "0.1.0" -description = "advent of code 2024-02" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/03/python.py b/2024/03/python.py new file mode 100755 index 0000000..f456580 --- /dev/null +++ b/2024/03/python.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +import re +from fileinput import input + +s = "\n".join(input()) + +silver = sum(int(x) * int(y) for x, y in re.findall(r"mul\((\d{1,3}),(\d{1,3})\)", s)) + +gold = 0 +active = True +for g in re.findall(r"(?:mul\((\d{1,3}),(\d{1,3})\))|(don't\(\))|(do\(\))", s): + match g, active: + case (x, y, "", ""), True: + gold += int(x) * int(y) + case (_, _, "don't()", _), _: + active = False + case (_, _, _, "do()"), _: + active = True + + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/03/python/main.py b/2024/03/python/main.py deleted file mode 100644 index f5617b5..0000000 --- a/2024/03/python/main.py +++ /dev/null @@ -1,21 +0,0 @@ -import re -from fileinput import input - -s = "\n".join(input()) - -silver = sum(int(x) * int(y) for x, y in re.findall(r"mul\((\d{1,3}),(\d{1,3})\)", s)) - -gold = 0 -active = True -for g in re.findall(r"(?:mul\((\d{1,3}),(\d{1,3})\))|(don't\(\))|(do\(\))", s): - match g, active: - case (x, y, "", ""), True: - gold += int(x) * int(y) - case (_, _, "don't()", _), _: - active = False - case (_, _, _, "do()"), _: - active = True - - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/03/python/pyproject.toml b/2024/03/python/pyproject.toml deleted file mode 100644 index 683451d..0000000 --- a/2024/03/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-03" -version = "0.1.0" -description = "advent of code 2024-03" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/04/python.py b/2024/04/python.py new file mode 100755 index 0000000..fe5021b --- /dev/null +++ b/2024/04/python.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 + +from fileinput import input + +grid = { + complex(idx, idy): c + for idy, line in enumerate(input()) + for idx, c in enumerate(line.strip()) +} +dirs = {complex(dx, dy) for dx in [-1, 0, 1] for dy in [-1, 0, 1]} + + +def xmas(x, v): + return all(grid.get(x + n * v) == c for n, c in enumerate("XMAS")) + + +def x_mas(x, v): + return ( + grid.get(x) == "A" + and grid.get(x + v) == grid.get(x + 1j * v) == "M" + and grid.get(x - v) == grid.get(x - 1j * v) == "S" + ) + + +silver = sum(xmas(x, v) for x in grid.keys() for v in dirs) +gold = sum(x_mas(x, v) for x in grid.keys() for v in dirs if abs(v) > 1) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/04/python/main.py b/2024/04/python/main.py deleted file mode 100644 index cc04f04..0000000 --- a/2024/04/python/main.py +++ /dev/null @@ -1,27 +0,0 @@ -from fileinput import input - -grid = { - complex(idx, idy): c - for idy, line in enumerate(input()) - for idx, c in enumerate(line.strip()) -} -dirs = {complex(dx, dy) for dx in [-1, 0, 1] for dy in [-1, 0, 1]} - - -def xmas(x, v): - return all(grid.get(x + n * v) == c for n, c in enumerate("XMAS")) - - -def x_mas(x, v): - return ( - grid.get(x) == "A" - and grid.get(x + v) == grid.get(x + 1j * v) == "M" - and grid.get(x - v) == grid.get(x - 1j * v) == "S" - ) - - -silver = sum(xmas(x, v) for x in grid.keys() for v in dirs) -gold = sum(x_mas(x, v) for x in grid.keys() for v in dirs if abs(v) > 1) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/04/python/pyproject.toml b/2024/04/python/pyproject.toml deleted file mode 100644 index 141044b..0000000 --- a/2024/04/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-04" -version = "0.1.0" -description = "advent of code 2024-04" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/05/python.py b/2024/05/python.py new file mode 100755 index 0000000..9e81978 --- /dev/null +++ b/2024/05/python.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +from fileinput import input +from functools import cmp_to_key +from itertools import takewhile + +inp = map(str.strip, input()) +ordering = set(takewhile(bool, inp)) +us = list(inp) + + +def cmp(x, y): + return (f"{y}|{x}" in ordering) * 2 - 1 # hehe + + +silver = 0 +gold = 0 + +for u in us: + pre = u.split(",") + post = list(sorted(pre, key=cmp_to_key(cmp))) + + mid = int(post[len(post) // 2]) + if pre == post: + silver += mid + else: + gold += mid + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/05/python/main.py b/2024/05/python/main.py deleted file mode 100644 index e3a10e2..0000000 --- a/2024/05/python/main.py +++ /dev/null @@ -1,28 +0,0 @@ -from fileinput import input -from functools import cmp_to_key -from itertools import takewhile - -inp = map(str.strip, input()) -ordering = set(takewhile(bool, inp)) -us = list(inp) - - -def cmp(x, y): - return (f"{y}|{x}" in ordering) * 2 - 1 # hehe - - -silver = 0 -gold = 0 - -for u in us: - pre = u.split(",") - post = list(sorted(pre, key=cmp_to_key(cmp))) - - mid = int(post[len(post) // 2]) - if pre == post: - silver += mid - else: - gold += mid - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/05/python/pyproject.toml b/2024/05/python/pyproject.toml deleted file mode 100644 index 720c539..0000000 --- a/2024/05/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-05" -version = "0.1.0" -description = "advent of code 2024-05" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/06/python.py b/2024/06/python.py new file mode 100755 index 0000000..52b61d0 --- /dev/null +++ b/2024/06/python.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +from fileinput import input + +obstacles = set() +seen = set() + +xmax, ymax = 0, 0 +for idy, line in enumerate(input()): + ymax = max(ymax, idy) + for idx, c in enumerate(line.strip()): + xmax = max(xmax, idx) + match c: + case "^": + pos = complex(idx, idy) + dir = 0 - 1j + case "#": + obstacles.add(complex(idx, idy)) + + +def is_loop(pos, obst): + seen_ = set() + dir = 0 - 1j + while 0 <= pos.real <= xmax and 0 <= pos.imag <= ymax: + if (pos, dir) in seen_: + return True + seen_.add((pos, dir)) + if pos + dir in obstacles or pos + dir == obst: + # Rotate cw + dir *= 1j + continue + pos += dir + return False + + +gold = 0 +for idx in range(xmax + 1): + for idy in range(ymax + 1): + if complex(idx, idy) == pos: + continue + else: + gold += is_loop(pos, complex(idx, idy)) + + +while 0 <= pos.real <= xmax and 0 <= pos.imag <= ymax: + seen.add(pos) + if pos + dir in obstacles: + # Rotate cw + dir *= 1j + continue + pos += dir + + +silver = len(seen) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/06/python/main.py b/2024/06/python/main.py deleted file mode 100644 index 5fd6c3d..0000000 --- a/2024/06/python/main.py +++ /dev/null @@ -1,55 +0,0 @@ -from fileinput import input - -obstacles = set() -seen = set() - -xmax, ymax = 0, 0 -for idy, line in enumerate(input()): - ymax = max(ymax, idy) - for idx, c in enumerate(line.strip()): - xmax = max(xmax, idx) - match c: - case "^": - pos = complex(idx, idy) - dir = 0 - 1j - case "#": - obstacles.add(complex(idx, idy)) - - -def is_loop(pos, obst): - seen_ = set() - dir = 0 - 1j - while 0 <= pos.real <= xmax and 0 <= pos.imag <= ymax: - if (pos, dir) in seen_: - return True - seen_.add((pos, dir)) - if pos + dir in obstacles or pos + dir == obst: - # Rotate cw - dir *= 1j - continue - pos += dir - return False - - -gold = 0 -for idx in range(xmax + 1): - for idy in range(ymax + 1): - if complex(idx, idy) == pos: - continue - else: - gold += is_loop(pos, complex(idx, idy)) - - -while 0 <= pos.real <= xmax and 0 <= pos.imag <= ymax: - seen.add(pos) - if pos + dir in obstacles: - # Rotate cw - dir *= 1j - continue - pos += dir - - -silver = len(seen) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/06/python/pyproject.toml b/2024/06/python/pyproject.toml deleted file mode 100644 index 8ad63e7..0000000 --- a/2024/06/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-06" -version = "0.1.0" -description = "advent of code 2024-06" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/07/python.py b/2024/07/python.py new file mode 100755 index 0000000..008af39 --- /dev/null +++ b/2024/07/python.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +from fileinput import input + +lines = [line.strip() for line in input()] + + +def solve(w, acc, rest, gold=False): + if not rest: + return w == acc + if w < acc: + return False + head, *rest = rest + return ( + solve(w, acc + head, rest, gold) + or solve(w, acc * head, rest, gold) + or (gold and solve(w, int(str(acc) + str(head)), rest, gold)) + ) + + +silver = 0 +gold = 0 + +for line in lines: + want, nums = line.split(":") + want = int(want) + nums = [int(n) for n in nums.split()] + head, *rest = nums + + if solve(want, head, rest): + silver += want + if solve(want, head, rest, True): + gold += want + + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/07/python/main.py b/2024/07/python/main.py deleted file mode 100644 index 0e72772..0000000 --- a/2024/07/python/main.py +++ /dev/null @@ -1,35 +0,0 @@ -from fileinput import input - -lines = [line.strip() for line in input()] - - -def solve(w, acc, rest, gold=False): - if not rest: - return w == acc - if w < acc: - return False - head, *rest = rest - return ( - solve(w, acc + head, rest, gold) - or solve(w, acc * head, rest, gold) - or (gold and solve(w, int(str(acc) + str(head)), rest, gold)) - ) - - -silver = 0 -gold = 0 - -for line in lines: - want, nums = line.split(":") - want = int(want) - nums = [int(n) for n in nums.split()] - head, *rest = nums - - if solve(want, head, rest): - silver += want - if solve(want, head, rest, True): - gold += want - - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/07/python/pyproject.toml b/2024/07/python/pyproject.toml deleted file mode 100644 index bbd42d3..0000000 --- a/2024/07/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-07" -version = "0.1.0" -description = "advent of code 2024-07" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/08/python.py b/2024/08/python.py new file mode 100755 index 0000000..783203b --- /dev/null +++ b/2024/08/python.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +from collections import defaultdict +from fileinput import input +from itertools import product + +antennas = defaultdict(set) +x_max, y_max = 0, 0 + +for idy, line in enumerate(input()): + y_max = max(y_max, idy) + for idx, c in enumerate(line.strip()): + x_max = max(x_max, idx) + if c == ".": + continue + + antennas[c].add(complex(idx, idy)) + +nodes = set() +for vs in antennas.values(): + for v1, v2 in product(vs, vs): + if v1 == v2: + continue + vec = v2 - v1 + nodes.add(v1 + 2 * vec) + nodes.add(v2 - 2 * vec) + +nodes = {n for n in nodes if 0 <= n.real <= x_max and 0 <= n.imag <= y_max} + +gold_nodes = set() +for vs in antennas.values(): + for v1, v2 in product(vs, vs): + if v1 == v2: + continue + vec = v2 - v1 + start = v1 + while 0 <= start.real <= x_max and 0 <= start.imag <= y_max: + gold_nodes.add(start) + start += vec + + start = v2 + while 0 <= start.real <= x_max and 0 <= start.imag <= y_max: + gold_nodes.add(start) + start -= vec + + +silver = len(nodes) +gold = len(gold_nodes) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/08/python/main.py b/2024/08/python/main.py deleted file mode 100644 index c7bb47d..0000000 --- a/2024/08/python/main.py +++ /dev/null @@ -1,49 +0,0 @@ -from collections import defaultdict -from fileinput import input -from itertools import product - -antennas = defaultdict(set) -x_max, y_max = 0, 0 - -for idy, line in enumerate(input()): - y_max = max(y_max, idy) - for idx, c in enumerate(line.strip()): - x_max = max(x_max, idx) - if c == ".": - continue - - antennas[c].add(complex(idx, idy)) - -nodes = set() -for vs in antennas.values(): - for v1, v2 in product(vs, vs): - if v1 == v2: - continue - vec = v2 - v1 - nodes.add(v1 + 2 * vec) - nodes.add(v2 - 2 * vec) - -nodes = {n for n in nodes if 0 <= n.real <= x_max and 0 <= n.imag <= y_max} - -gold_nodes = set() -for vs in antennas.values(): - for v1, v2 in product(vs, vs): - if v1 == v2: - continue - vec = v2 - v1 - start = v1 - while 0 <= start.real <= x_max and 0 <= start.imag <= y_max: - gold_nodes.add(start) - start += vec - - start = v2 - while 0 <= start.real <= x_max and 0 <= start.imag <= y_max: - gold_nodes.add(start) - start -= vec - - -silver = len(nodes) -gold = len(gold_nodes) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/08/python/pyproject.toml b/2024/08/python/pyproject.toml deleted file mode 100644 index e00a133..0000000 --- a/2024/08/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-08" -version = "0.1.0" -description = "advent of code 2024-08" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/09/python.py b/2024/09/python.py new file mode 100755 index 0000000..1cf450e --- /dev/null +++ b/2024/09/python.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +from fileinput import input + +disk = list(input())[0].strip() + +id_ = -1 +blocks = [] +tail = 0 +file = True +for c in disk: + blocks.append([tail, tail + int(c), (id_ := id_ + 1) if file else -1]) + tail += int(c) + file = not file + + +def expand(bs): + return [x for a, b, x in sorted(bs) for _ in range(b - a)] + + +def debug(bs): + print("".join(str(b) if b != -1 else "." for b in expand(bs))) + + +# Silver +expanded = expand(blocks) +tail = len(expanded) - 1 +fill = expanded.index(-1) +while fill < tail: + expanded[fill] = expanded[tail] + expanded[tail] = -1 + while expanded[tail] == -1: + tail -= 1 + while expanded[fill] != -1: + fill += 1 +silver = sum(idx * n for idx, n in enumerate(expanded) if n != -1) + + +# Gold +for move in blocks[::-1]: + print(move) + ma, mb, mx = move + if mx == -1: + continue + mlen = mb - ma + for tidx, to in enumerate(blocks): + ta, tb, tx = to + if ta >= ma: + break + if tx != -1: + continue + if (tlen := tb - ta) < mlen: + continue + move[2] = -1 + to[2] = mx + to[1] = ta + mlen + blocks.insert(tidx + 1, [ta + mlen, tb, -1]) + break +gold = sum(idx * n for idx, n in enumerate(expand(blocks)) if n != -1) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/09/python/main.py b/2024/09/python/main.py deleted file mode 100644 index d435163..0000000 --- a/2024/09/python/main.py +++ /dev/null @@ -1,60 +0,0 @@ -from fileinput import input - -disk = list(input())[0].strip() - -id_ = -1 -blocks = [] -tail = 0 -file = True -for c in disk: - blocks.append([tail, tail + int(c), (id_ := id_ + 1) if file else -1]) - tail += int(c) - file = not file - - -def expand(bs): - return [x for a, b, x in sorted(bs) for _ in range(b - a)] - - -def debug(bs): - print("".join(str(b) if b != -1 else "." for b in expand(bs))) - - -# Silver -expanded = expand(blocks) -tail = len(expanded) - 1 -fill = expanded.index(-1) -while fill < tail: - expanded[fill] = expanded[tail] - expanded[tail] = -1 - while expanded[tail] == -1: - tail -= 1 - while expanded[fill] != -1: - fill += 1 -silver = sum(idx * n for idx, n in enumerate(expanded) if n != -1) - - -# Gold -for move in blocks[::-1]: - print(move) - ma, mb, mx = move - if mx == -1: - continue - mlen = mb - ma - for tidx, to in enumerate(blocks): - ta, tb, tx = to - if ta >= ma: - break - if tx != -1: - continue - if (tlen := tb - ta) < mlen: - continue - move[2] = -1 - to[2] = mx - to[1] = ta + mlen - blocks.insert(tidx + 1, [ta + mlen, tb, -1]) - break -gold = sum(idx * n for idx, n in enumerate(expand(blocks)) if n != -1) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/09/python/pyproject.toml b/2024/09/python/pyproject.toml deleted file mode 100644 index 66c042a..0000000 --- a/2024/09/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-09" -version = "0.1.0" -description = "advent of code 2024-09" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/10/python.py b/2024/10/python.py new file mode 100755 index 0000000..88892b6 --- /dev/null +++ b/2024/10/python.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +from fileinput import input + +grid = [[int(c) for c in line.strip()] for line in input()] + +starts = { + (idx, idy) for idy, line in enumerate(grid) for idx, n in enumerate(line) if n == 0 +} + +# print(*grid, sep="\n") +# print(starts) + + +def score_trailhead(start, gold): + score = 0 + q = [start] + seen = set() + while q: + x, y = q.pop() + seen.add((x, y)) + + h = grid[y][x] + if h == 9: + score += 1 + continue + for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]: + nx, ny = x + dx, y + dy + if ((nx, ny) in seen and not gold) or not ( + 0 <= nx < len(grid) and 0 <= ny < len(grid[0]) + ): + continue + + if grid[ny][nx] == h + 1: + q.append((nx, ny)) + return score + + +silver = sum(score_trailhead(start, False) for start in starts) +gold = sum(score_trailhead(start, True) for start in starts) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/10/python/main.py b/2024/10/python/main.py deleted file mode 100644 index 4e85b49..0000000 --- a/2024/10/python/main.py +++ /dev/null @@ -1,41 +0,0 @@ -from fileinput import input - -grid = [[int(c) for c in line.strip()] for line in input()] - -starts = { - (idx, idy) for idy, line in enumerate(grid) for idx, n in enumerate(line) if n == 0 -} - -# print(*grid, sep="\n") -# print(starts) - - -def score_trailhead(start, gold): - score = 0 - q = [start] - seen = set() - while q: - x, y = q.pop() - seen.add((x, y)) - - h = grid[y][x] - if h == 9: - score += 1 - continue - for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]: - nx, ny = x + dx, y + dy - if ((nx, ny) in seen and not gold) or not ( - 0 <= nx < len(grid) and 0 <= ny < len(grid[0]) - ): - continue - - if grid[ny][nx] == h + 1: - q.append((nx, ny)) - return score - - -silver = sum(score_trailhead(start, False) for start in starts) -gold = sum(score_trailhead(start, True) for start in starts) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/10/python/pyproject.toml b/2024/10/python/pyproject.toml deleted file mode 100644 index 8458dc5..0000000 --- a/2024/10/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-10" -version = "0.1.0" -description = "advent of code 2024-10" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/11/python.py b/2024/11/python.py new file mode 100755 index 0000000..37f658e --- /dev/null +++ b/2024/11/python.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +from fileinput import input +from functools import cache +from math import floor, log + +stones = [int(x) for x in input().readline().split()] + + +@cache +def blink(s, n): + if n == 0: + return 1 + + if s == 0: + return blink(1, n - 1) + + digits = floor(log(s, 10) + 1e-6) + 1 + if digits % 2 == 0: + left, right = divmod(s, 10 ** (digits // 2)) + return blink(left, n - 1) + blink(right, n - 1) + + return blink(s * 2024, n - 1) + + +silver = sum(blink(s, 25) for s in stones) +gold = sum(blink(s, 75) for s in stones) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/11/python/main.py b/2024/11/python/main.py deleted file mode 100644 index 445809a..0000000 --- a/2024/11/python/main.py +++ /dev/null @@ -1,28 +0,0 @@ -from fileinput import input -from functools import cache -from math import floor, log - -stones = [int(x) for x in input().readline().split()] - - -@cache -def blink(s, n): - if n == 0: - return 1 - - if s == 0: - return blink(1, n - 1) - - digits = floor(log(s, 10) + 1e-6) + 1 - if digits % 2 == 0: - left, right = divmod(s, 10 ** (digits // 2)) - return blink(left, n - 1) + blink(right, n - 1) - - return blink(s * 2024, n - 1) - - -silver = sum(blink(s, 25) for s in stones) -gold = sum(blink(s, 75) for s in stones) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/11/python/pyproject.toml b/2024/11/python/pyproject.toml deleted file mode 100644 index aa72c8e..0000000 --- a/2024/11/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-11" -version = "0.1.0" -description = "advent of code 2024-11" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/12/python.py b/2024/12/python.py new file mode 100755 index 0000000..81761bc --- /dev/null +++ b/2024/12/python.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 + +from fileinput import input + +grid = { + complex(idx, idy): c + for idy, line in enumerate(input()) + for idx, c in enumerate(line.strip()) +} +xmax = int(max(x.real for x in grid.keys())) +ymax = int(max(x.imag for x in grid.keys())) + +seen = set() + +silver = 0 + +for x in range(xmax + 1): + for y in range(ymax + 1): + c = complex(x, y) + if c in seen: + continue + + # Flood fill + char = grid[c] + perimeter = area = 0 + queue = [c] + while queue: + curr = queue.pop() + if curr in seen: + continue + seen.add(curr) + + for dir in [1, -1, 1j, -1j]: + next_ = curr + dir + if ( + not (0 <= next_.real <= xmax and 0 <= next_.imag <= ymax) + or grid[next_] != char + ): + perimeter += 1 + continue + + queue.append(next_) + area += 1 + silver += perimeter * area + +gold = 0 + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/12/python/main.py b/2024/12/python/main.py deleted file mode 100644 index 6faa6f1..0000000 --- a/2024/12/python/main.py +++ /dev/null @@ -1,47 +0,0 @@ -from fileinput import input - -grid = { - complex(idx, idy): c - for idy, line in enumerate(input()) - for idx, c in enumerate(line.strip()) -} -xmax = int(max(x.real for x in grid.keys())) -ymax = int(max(x.imag for x in grid.keys())) - -seen = set() - -silver = 0 - -for x in range(xmax + 1): - for y in range(ymax + 1): - c = complex(x, y) - if c in seen: - continue - - # Flood fill - char = grid[c] - perimeter = area = 0 - queue = [c] - while queue: - curr = queue.pop() - if curr in seen: - continue - seen.add(curr) - - for dir in [1, -1, 1j, -1j]: - next_ = curr + dir - if ( - not (0 <= next_.real <= xmax and 0 <= next_.imag <= ymax) - or grid[next_] != char - ): - perimeter += 1 - continue - - queue.append(next_) - area += 1 - silver += perimeter * area - -gold = 0 - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/12/python/pyproject.toml b/2024/12/python/pyproject.toml deleted file mode 100644 index b36941b..0000000 --- a/2024/12/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-12" -version = "0.1.0" -description = "advent of code 2024-12" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/13/python.py b/2024/13/python.py new file mode 100755 index 0000000..e78e35f --- /dev/null +++ b/2024/13/python.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +import re +from fileinput import input +from itertools import batched + +lines = [line.strip() for line in input()] + + +re_button = r"Button [A|B]: X\+(\d+), Y\+(\d+)" +re_prize = r"Prize: X=(\d+), Y=(\d+)" + + +def solve(machine, gold): + m = re.fullmatch( + r"Button A: X\+(\d+), Y\+(\d+)Button B: X\+(\d+), Y\+(\d+)Prize: X=(\d+), Y=(\d+)", + "".join(machine), + ) + # 2x2 matrix solve + ax, ay, bx, by, px, py = map(int, m.groups()) + if gold: + px += 10000000000000 + py += 10000000000000 + det = ax * by - ay * bx + + A = (by * px - bx * py) / det + B = (-ay * px + ax * py) / det + + # Check solutions are ints + if abs(int(A) - A) < 1e-7 and abs(int(B) - B) < 1e-7: + return 3 * int(A) + int(B) + else: + return 0 + + +silver = sum(solve(b, False) for b in batched(lines, 4)) +gold = sum(solve(b, True) for b in batched(lines, 4)) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/13/python/main.py b/2024/13/python/main.py deleted file mode 100644 index de31184..0000000 --- a/2024/13/python/main.py +++ /dev/null @@ -1,38 +0,0 @@ -import re -from fileinput import input -from itertools import batched - -lines = [line.strip() for line in input()] - - -re_button = r"Button [A|B]: X\+(\d+), Y\+(\d+)" -re_prize = r"Prize: X=(\d+), Y=(\d+)" - - -def solve(machine, gold): - m = re.fullmatch( - r"Button A: X\+(\d+), Y\+(\d+)Button B: X\+(\d+), Y\+(\d+)Prize: X=(\d+), Y=(\d+)", - "".join(machine), - ) - # 2x2 matrix solve - ax, ay, bx, by, px, py = map(int, m.groups()) - if gold: - px += 10000000000000 - py += 10000000000000 - det = ax * by - ay * bx - - A = (by * px - bx * py) / det - B = (-ay * px + ax * py) / det - - # Check solutions are ints - if abs(int(A) - A) < 1e-7 and abs(int(B) - B) < 1e-7: - return 3 * int(A) + int(B) - else: - return 0 - - -silver = sum(solve(b, False) for b in batched(lines, 4)) -gold = sum(solve(b, True) for b in batched(lines, 4)) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/13/python/pyproject.toml b/2024/13/python/pyproject.toml deleted file mode 100644 index aae82b9..0000000 --- a/2024/13/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-13" -version = "0.1.0" -description = "advent of code 2024-13" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/14/python.py b/2024/14/python.py new file mode 100755 index 0000000..2bb6cb4 --- /dev/null +++ b/2024/14/python.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 + +import re +from fileinput import input +from itertools import groupby +from math import prod + +XMAX, YMAX = 11, 7 # for test +XMAX, YMAX = 101, 103 # for aoc + +robots = [ + re.fullmatch(r"p=(\d+),(\d+) v=(-?\d+),(-?\d+)", line.strip()).groups() + for line in input() +] +robots = [ + (complex(int(px), int(py)), complex(int(vx), int(vy))) for px, py, vx, vy in robots +] + + +def move(p, v, s): + e = p + v * s + return complex(e.real % XMAX, e.imag % YMAX) + + +def quad(x): + return (x.real < XMAX // 2, x.imag < YMAX // 2) + + +def is_quad(x): + return x.real != XMAX // 2 and x.imag != YMAX // 2 + + +def draw(s): + print(f"Seconds passed: {s}") + moved = {move(p, v, s) for p, v in robots} + for x in range(XMAX): + for y in range(YMAX): + print( + "#" if complex(x, y) in moved else " ", + end="", + ) + print() + print("-" * XMAX) + + +moved = groupby( + sorted( + filter(is_quad, (move(p, v, 100) for p, v in robots)), + key=quad, + ), + quad, +) + + +silver = prod(sum(1 for _ in k) for _, k in moved) +gold = 0 + +print("silver:", silver) +print("gold:", gold) + +s = 0 +while s < 10_000: + draw(s) + s += 1 diff --git a/2024/14/python/main.py b/2024/14/python/main.py deleted file mode 100644 index ebfe29c..0000000 --- a/2024/14/python/main.py +++ /dev/null @@ -1,62 +0,0 @@ -import re -from fileinput import input -from itertools import groupby -from math import prod - -XMAX, YMAX = 11, 7 # for test -XMAX, YMAX = 101, 103 # for aoc - -robots = [ - re.fullmatch(r"p=(\d+),(\d+) v=(-?\d+),(-?\d+)", line.strip()).groups() - for line in input() -] -robots = [ - (complex(int(px), int(py)), complex(int(vx), int(vy))) for px, py, vx, vy in robots -] - - -def move(p, v, s): - e = p + v * s - return complex(e.real % XMAX, e.imag % YMAX) - - -def quad(x): - return (x.real < XMAX // 2, x.imag < YMAX // 2) - - -def is_quad(x): - return x.real != XMAX // 2 and x.imag != YMAX // 2 - - -def draw(s): - print(f"Seconds passed: {s}") - moved = {move(p, v, s) for p, v in robots} - for x in range(XMAX): - for y in range(YMAX): - print( - "#" if complex(x, y) in moved else " ", - end="", - ) - print() - print("-" * XMAX) - - -moved = groupby( - sorted( - filter(is_quad, (move(p, v, 100) for p, v in robots)), - key=quad, - ), - quad, -) - - -silver = prod(sum(1 for _ in k) for _, k in moved) -gold = 0 - -print("silver:", silver) -print("gold:", gold) - -s = 0 -while s < 10_000: - draw(s) - s += 1 diff --git a/2024/14/python/pyproject.toml b/2024/14/python/pyproject.toml deleted file mode 100644 index 45527a8..0000000 --- a/2024/14/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-14" -version = "0.1.0" -description = "advent of code 2024-14" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/15/python.py b/2024/15/python.py new file mode 100755 index 0000000..4cfd48c --- /dev/null +++ b/2024/15/python.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 + +from fileinput import input +from itertools import takewhile + +inp = map(str.strip, input()) + +grid = { + complex(x, y): c + for y, line in enumerate(takewhile(bool, inp)) + for x, c in enumerate(line) +} +grid_gold = {} +for p, c in grid.items(): + p += p.real + match c: + case "#" | ".": + grid_gold[p] = grid_gold[p + 1] = c + case "O": + grid_gold[p] = "[" + grid_gold[p + 1] = "]" + case "@": + grid_gold[p] = "@" + grid_gold[p + 1] = "." + + +moves = "".join(inp) + +bot = next(p for p, c in grid.items() if c == "@") +bot_gold = bot + bot.real + + +def debug(grid): + xmax, ymax = (max(p.real for p in grid.keys()), max(p.imag for p in grid.keys())) + for y in range(int(ymax) + 1): + for x in range(int(xmax) + 1): + print(grid[complex(x, y)], end="") + print() + print() + + +def push(grid, x, v, modify=True): + match grid[x], v: + case ".", _: + return True + case "#", _: + return False + case "[", (1j | -1j) if push(grid, x + v, v, modify) and push( + grid, x + v + 1, v, modify + ): + if modify: + grid[x + v] = grid[x] + grid[x + v + 1] = grid[x + 1] + grid[x] = "." + grid[x + 1] = "." + return True + case "[", (1j | -1j): + return False + # Push other one + case "]", (1j | -1j): + return push(grid, x - 1, v, modify) + case _, _ if push(grid, x + v, v, modify): + if modify: + grid[x + v] = grid[x] + return True + + +dirs = {">": 1, "v": 1j, "<": -1, "^": -1j} +for m in map(dirs.get, moves): + if push(grid, bot, m): + grid[bot] = "." + bot += m + if push(grid_gold, bot_gold, m, modify=False): + push(grid_gold, bot_gold, m, modify=True) + grid_gold[bot_gold] = "." + bot_gold += m + + +silver = int(sum(p.real + 100 * p.imag for p, c in grid.items() if c == "O")) +gold = int(sum(p.real + 100 * p.imag for p, c in grid_gold.items() if c == "[")) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/15/python/main.py b/2024/15/python/main.py deleted file mode 100644 index a565f00..0000000 --- a/2024/15/python/main.py +++ /dev/null @@ -1,81 +0,0 @@ -from fileinput import input -from itertools import takewhile - -inp = map(str.strip, input()) - -grid = { - complex(x, y): c - for y, line in enumerate(takewhile(bool, inp)) - for x, c in enumerate(line) -} -grid_gold = {} -for p, c in grid.items(): - p += p.real - match c: - case "#" | ".": - grid_gold[p] = grid_gold[p + 1] = c - case "O": - grid_gold[p] = "[" - grid_gold[p + 1] = "]" - case "@": - grid_gold[p] = "@" - grid_gold[p + 1] = "." - - -moves = "".join(inp) - -bot = next(p for p, c in grid.items() if c == "@") -bot_gold = bot + bot.real - - -def debug(grid): - xmax, ymax = (max(p.real for p in grid.keys()), max(p.imag for p in grid.keys())) - for y in range(int(ymax) + 1): - for x in range(int(xmax) + 1): - print(grid[complex(x, y)], end="") - print() - print() - - -def push(grid, x, v, modify=True): - match grid[x], v: - case ".", _: - return True - case "#", _: - return False - case "[", (1j | -1j) if push(grid, x + v, v, modify) and push( - grid, x + v + 1, v, modify - ): - if modify: - grid[x + v] = grid[x] - grid[x + v + 1] = grid[x + 1] - grid[x] = "." - grid[x + 1] = "." - return True - case "[", (1j | -1j): - return False - # Push other one - case "]", (1j | -1j): - return push(grid, x - 1, v, modify) - case _, _ if push(grid, x + v, v, modify): - if modify: - grid[x + v] = grid[x] - return True - - -dirs = {">": 1, "v": 1j, "<": -1, "^": -1j} -for m in map(dirs.get, moves): - if push(grid, bot, m): - grid[bot] = "." - bot += m - if push(grid_gold, bot_gold, m, modify=False): - push(grid_gold, bot_gold, m, modify=True) - grid_gold[bot_gold] = "." - bot_gold += m - - -silver = int(sum(p.real + 100 * p.imag for p, c in grid.items() if c == "O")) -gold = int(sum(p.real + 100 * p.imag for p, c in grid_gold.items() if c == "[")) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/15/python/pyproject.toml b/2024/15/python/pyproject.toml deleted file mode 100644 index 0dfbb68..0000000 --- a/2024/15/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-15" -version = "0.1.0" -description = "advent of code 2024-15" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/16/python.py b/2024/16/python.py new file mode 100755 index 0000000..fda3714 --- /dev/null +++ b/2024/16/python.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 + +from fileinput import input + +grid = { + complex(idx, idy): c + for idy, line in enumerate(input()) + for idx, c in enumerate(line.strip()) +} +start = next(p for p, c in grid.items() if c == "S") +end = next(p for p, c in grid.items() if c == "E") + +q = [(0, (start, 1))] +seen = set() +while q: + curr = min(q, key=lambda x: x[0]) + d, (pos, vel) = curr + q.remove(curr) + if (pos, vel) in seen: + continue + if pos == end: + silver = d + break + seen.add((pos, vel)) + + if grid[pos + vel] != "#": + q.append((d + 1, (pos + vel, vel))) + q.append((d + 1000, (pos, vel * 1j))) + q.append((d + 1000, (pos, vel * -1j))) + +print("silver:", silver) diff --git a/2024/16/python/main.py b/2024/16/python/main.py deleted file mode 100644 index f66fe94..0000000 --- a/2024/16/python/main.py +++ /dev/null @@ -1,29 +0,0 @@ -from fileinput import input - -grid = { - complex(idx, idy): c - for idy, line in enumerate(input()) - for idx, c in enumerate(line.strip()) -} -start = next(p for p, c in grid.items() if c == "S") -end = next(p for p, c in grid.items() if c == "E") - -q = [(0, (start, 1))] -seen = set() -while q: - curr = min(q, key=lambda x: x[0]) - d, (pos, vel) = curr - q.remove(curr) - if (pos, vel) in seen: - continue - if pos == end: - silver = d - break - seen.add((pos, vel)) - - if grid[pos + vel] != "#": - q.append((d + 1, (pos + vel, vel))) - q.append((d + 1000, (pos, vel * 1j))) - q.append((d + 1000, (pos, vel * -1j))) - -print("silver:", silver) diff --git a/2024/16/python/pyproject.toml b/2024/16/python/pyproject.toml deleted file mode 100644 index d38516f..0000000 --- a/2024/16/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-16" -version = "0.1.0" -description = "advent of code 2024-16" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/17/python.py b/2024/17/python.py new file mode 100755 index 0000000..9ea7de4 --- /dev/null +++ b/2024/17/python.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 + +from fileinput import input +from itertools import takewhile, zip_longest + +inp = map(str.strip, input()) +regs = [int(r[2]) for r in (line.split() for line in takewhile(bool, inp))] +prog = [int(o) for o in next(inp).split()[1].split(",")] +out = [] + + +def run(prog, ra, rb, rc): + out = [] + ir = 0 + while ir < len(prog): + instr, op = prog[ir], prog[ir + 1] + combo = {4: ra, 5: rb, 6: rc} + cop = combo.get(op, op) + match instr: + case 0: + ra = ra >> cop + case 1: + rb ^= op + case 2: + rb = cop & 0b111 + case 3 if ra: + ir = op - 2 + case 4: + rb ^= rc + case 5: + yield cop & 0b111 + case 6: + rb = ra >> cop + case 7: + rc = ra >> cop + ir += 2 + return out + + +def match(prog, ra): + return ( + got == want + for got, want in zip_longest( + reversed(list(run(prog, ra, 0, 0))), + reversed(prog), + ) + ) + + +def find_a(prog): + q = list(range(8)) + while True: + curr = q.pop(0) + if all(match(prog, curr)): + return curr + + best = sum(match(prog, curr)) + for n in range(8): + ra = (curr << 3) + n + if sum(match(prog, ra)) > best: + q.append(ra) + + +silver = ",".join(map(str, run(prog, *regs))) +gold = find_a(prog) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/17/python/main.py b/2024/17/python/main.py deleted file mode 100644 index a441d40..0000000 --- a/2024/17/python/main.py +++ /dev/null @@ -1,66 +0,0 @@ -from fileinput import input -from itertools import takewhile, zip_longest - -inp = map(str.strip, input()) -regs = [int(r[2]) for r in (line.split() for line in takewhile(bool, inp))] -prog = [int(o) for o in next(inp).split()[1].split(",")] -out = [] - - -def run(prog, ra, rb, rc): - out = [] - ir = 0 - while ir < len(prog): - instr, op = prog[ir], prog[ir + 1] - combo = {4: ra, 5: rb, 6: rc} - cop = combo.get(op, op) - match instr: - case 0: - ra = ra >> cop - case 1: - rb ^= op - case 2: - rb = cop & 0b111 - case 3 if ra: - ir = op - 2 - case 4: - rb ^= rc - case 5: - yield cop & 0b111 - case 6: - rb = ra >> cop - case 7: - rc = ra >> cop - ir += 2 - return out - - -def match(prog, ra): - return ( - got == want - for got, want in zip_longest( - reversed(list(run(prog, ra, 0, 0))), - reversed(prog), - ) - ) - - -def find_a(prog): - q = list(range(8)) - while True: - curr = q.pop(0) - if all(match(prog, curr)): - return curr - - best = sum(match(prog, curr)) - for n in range(8): - ra = (curr << 3) + n - if sum(match(prog, ra)) > best: - q.append(ra) - - -silver = ",".join(map(str, run(prog, *regs))) -gold = find_a(prog) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/17/python/pyproject.toml b/2024/17/python/pyproject.toml deleted file mode 100644 index daf149a..0000000 --- a/2024/17/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-17" -version = "0.1.0" -description = "advent of code 2024-17" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/18/python.py b/2024/18/python.py new file mode 100755 index 0000000..1f987c6 --- /dev/null +++ b/2024/18/python.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 + +from bisect import bisect_left +from collections import deque +from fileinput import input + +coords = [line.strip().split(",") for line in input()] +grid = {complex(int(x), int(y)): t for t, [x, y] in enumerate(coords)} + + +def solve(size, delay): + q = deque([(0, 0)]) + seen = set() + while q: + curr, t = q.popleft() + if curr in seen: + continue + if curr == complex(size, size): + return t + seen.add(curr) + + for d in [1, -1, 1j, -1j]: + x = curr + d + if not (0 <= x.real <= size and 0 <= x.imag <= size): + continue + if x in grid and grid[x] < delay: + continue + q.append((x, t + 1)) + return None + + +silver = solve(70, 1024) +# silver = solve(6, 12) # test.txt + +gold = ",".join( + coords[ + bisect_left( + list(range(len(grid))), + True, + key=lambda x: solve(70, x) is None, + ) + - 1 + ] +) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/18/python/main.py b/2024/18/python/main.py deleted file mode 100644 index 071fa90..0000000 --- a/2024/18/python/main.py +++ /dev/null @@ -1,45 +0,0 @@ -from bisect import bisect_left -from collections import deque -from fileinput import input - -coords = [line.strip().split(",") for line in input()] -grid = {complex(int(x), int(y)): t for t, [x, y] in enumerate(coords)} - - -def solve(size, delay): - q = deque([(0, 0)]) - seen = set() - while q: - curr, t = q.popleft() - if curr in seen: - continue - if curr == complex(size, size): - return t - seen.add(curr) - - for d in [1, -1, 1j, -1j]: - x = curr + d - if not (0 <= x.real <= size and 0 <= x.imag <= size): - continue - if x in grid and grid[x] < delay: - continue - q.append((x, t + 1)) - return None - - -silver = solve(70, 1024) -# silver = solve(6, 12) # test.txt - -gold = ",".join( - coords[ - bisect_left( - list(range(len(grid))), - True, - key=lambda x: solve(70, x) is None, - ) - - 1 - ] -) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/18/python/pyproject.toml b/2024/18/python/pyproject.toml deleted file mode 100644 index f1deef2..0000000 --- a/2024/18/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-18" -version = "0.1.0" -description = "advent of code 2024-18" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/19/python.py b/2024/19/python.py new file mode 100755 index 0000000..efd3272 --- /dev/null +++ b/2024/19/python.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 + +from fileinput import input +from functools import cache +from itertools import takewhile + +inp = map(str.strip, input()) +towels = [t.strip() for t in next(takewhile(bool, inp)).split(",")] +designs = [d for d in inp if d] + +# Construct trie +trie = {} +for towel in towels: + prev = None + curr = trie + for t in towel: + term, succ = curr.setdefault(t, (False, {})) + prev = curr + curr = succ + prev[towel[-1]] = (True, curr) + + +@cache +def steps(design, n=0): + if n == len(design): + return 1 + ways = 0 + curr = trie + for d, s in enumerate(design[n:], start=1): + if s not in curr: + return ways + term, curr = curr[s] + if term: + ways += steps(design, n + d) + return ways + + +silver = sum(map(bool, map(steps, designs))) +gold = sum(map(steps, designs)) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/19/python/main.py b/2024/19/python/main.py deleted file mode 100644 index a41156c..0000000 --- a/2024/19/python/main.py +++ /dev/null @@ -1,40 +0,0 @@ -from fileinput import input -from functools import cache -from itertools import takewhile - -inp = map(str.strip, input()) -towels = [t.strip() for t in next(takewhile(bool, inp)).split(",")] -designs = [d for d in inp if d] - -# Construct trie -trie = {} -for towel in towels: - prev = None - curr = trie - for t in towel: - term, succ = curr.setdefault(t, (False, {})) - prev = curr - curr = succ - prev[towel[-1]] = (True, curr) - - -@cache -def steps(design, n=0): - if n == len(design): - return 1 - ways = 0 - curr = trie - for d, s in enumerate(design[n:], start=1): - if s not in curr: - return ways - term, curr = curr[s] - if term: - ways += steps(design, n + d) - return ways - - -silver = sum(map(bool, map(steps, designs))) -gold = sum(map(steps, designs)) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/19/python/pyproject.toml b/2024/19/python/pyproject.toml deleted file mode 100644 index 539ef74..0000000 --- a/2024/19/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-19" -version = "0.1.0" -description = "advent of code 2024-19" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/20/python.py b/2024/20/python.py new file mode 100755 index 0000000..610f1a3 --- /dev/null +++ b/2024/20/python.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +from fileinput import input + +grid = { + complex(idx, idy): c + for idy, line in enumerate(input()) + for idx, c in enumerate(line.strip()) +} +start = next(p for p, c in grid.items() if c == "S") +end = next(p for p, c in grid.items() if c == "E") + +times = {} +q = [(start, 0)] +while q: + curr, t = q.pop() + if curr in times: + continue + times[curr] = t + for d in [1, -1, 1j, -1j]: + x = curr + d + if x not in grid or grid[x] == "#": + continue + q.append((x, t + 1)) + + +def cheat(x, y, d): + dist = int(abs(x.real - y.real) + abs(x.imag - y.imag)) + if dist > d: + return False + saved = times[y] - times[x] - dist + return saved >= 100 + + +silver = sum(cheat(x, y, 2) for x in times.keys() for y in times.keys()) +gold = sum(cheat(x, y, 20) for x in times.keys() for y in times.keys()) + + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/20/python/main.py b/2024/20/python/main.py deleted file mode 100644 index bec6ebf..0000000 --- a/2024/20/python/main.py +++ /dev/null @@ -1,38 +0,0 @@ -from fileinput import input - -grid = { - complex(idx, idy): c - for idy, line in enumerate(input()) - for idx, c in enumerate(line.strip()) -} -start = next(p for p, c in grid.items() if c == "S") -end = next(p for p, c in grid.items() if c == "E") - -times = {} -q = [(start, 0)] -while q: - curr, t = q.pop() - if curr in times: - continue - times[curr] = t - for d in [1, -1, 1j, -1j]: - x = curr + d - if x not in grid or grid[x] == "#": - continue - q.append((x, t + 1)) - - -def cheat(x, y, d): - dist = int(abs(x.real - y.real) + abs(x.imag - y.imag)) - if dist > d: - return False - saved = times[y] - times[x] - dist - return saved >= 100 - - -silver = sum(cheat(x, y, 2) for x in times.keys() for y in times.keys()) -gold = sum(cheat(x, y, 20) for x in times.keys() for y in times.keys()) - - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/20/python/pyproject.toml b/2024/20/python/pyproject.toml deleted file mode 100644 index 4031bd1..0000000 --- a/2024/20/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-20" -version = "0.1.0" -description = "advent of code 2024-20" -requires-python = ">=3.13" -dependencies = [] diff --git a/2024/21/python.py b/2024/21/python.py new file mode 100755 index 0000000..5873d65 --- /dev/null +++ b/2024/21/python.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 + +from fileinput import input +from functools import cache + +seqs = [s.strip() for s in input()] + +numpad = { + "0": {"^": "2", ">": "A"}, + "1": {"^": "4", ">": "2"}, + "2": {"^": "5", ">": "3", "v": "0", "<": "1"}, + "3": {"^": "6", "v": "A", "<": "2"}, + "4": {"^": "7", ">": "5", "v": "1"}, + "5": {"^": "8", ">": "6", "v": "2", "<": "4"}, + "6": {"^": "9", "v": "3", "<": "5"}, + "7": {">": "8", "v": "4"}, + "8": {">": "9", "v": "5", "<": "7"}, + "9": {"v": "6", "<": "8"}, + "A": {"^": "3", "<": "0"}, +} +dirpad = { + "^": {">": "A", "v": "v"}, + ">": {"^": "A", "<": "v"}, + "v": {"^": "^", ">": ">", "<": "<"}, + "<": {">": "v"}, + "A": {"v": ">", "<": "^"}, +} + + +silver = 0 +gold = 0 + + +@cache +def move(a, b, n): + pass + + +print(seqs) + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/22/python.py b/2024/22/python.py new file mode 100755 index 0000000..98d8898 --- /dev/null +++ b/2024/22/python.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 + +from collections import Counter, deque +from fileinput import input +from itertools import islice + +lines = [int(line.strip()) for line in input()] + + +def secrets(secret): + x = secret + while True: + yield x + x ^= x << 6 + x &= 0xFFFFFF + x ^= x >> 5 + x &= 0xFFFFFF + x ^= x << 11 + x &= 0xFFFFFF + + +def prices(it): + for s in it: + yield s % 10 + + +def diff(it): + prev = next(it) + for curr in it: + yield curr, curr - prev + prev = curr + + +def to_seqs(it, n=4): + head = map(lambda x: x[1], islice(it, n - 1)) + q = deque(head, maxlen=n) + for price, diff in it: + q.append(diff) + yield price, tuple(q) + + +def seq_sells(it): + sells = {} + for price, diff in it: + if diff in sells: + continue + sells[diff] = price + return sells + + +best_seqs = Counter() +for x in lines: + best_seqs += seq_sells(to_seqs(islice(diff(prices(secrets(x))), 2000))) + +silver = sum(next(islice(secrets(x), 2000, None)) for x in lines) +gold = best_seqs.most_common(1)[0][1] + +print("silver:", silver) +print("gold:", gold) diff --git a/2024/22/python/main.py b/2024/22/python/main.py deleted file mode 100644 index c290858..0000000 --- a/2024/22/python/main.py +++ /dev/null @@ -1,57 +0,0 @@ -from collections import Counter, deque -from fileinput import input -from itertools import islice - -lines = [int(line.strip()) for line in input()] - - -def secrets(secret): - x = secret - while True: - yield x - x ^= x << 6 - x &= 0xFFFFFF - x ^= x >> 5 - x &= 0xFFFFFF - x ^= x << 11 - x &= 0xFFFFFF - - -def prices(it): - for s in it: - yield s % 10 - - -def diff(it): - prev = next(it) - for curr in it: - yield curr, curr - prev - prev = curr - - -def to_seqs(it, n=4): - head = map(lambda x: x[1], islice(it, n - 1)) - q = deque(head, maxlen=n) - for price, diff in it: - q.append(diff) - yield price, tuple(q) - - -def seq_sells(it): - sells = {} - for price, diff in it: - if diff in sells: - continue - sells[diff] = price - return sells - - -best_seqs = Counter() -for x in lines: - best_seqs += seq_sells(to_seqs(islice(diff(prices(secrets(x))), 2000))) - -silver = sum(next(islice(secrets(x), 2000, None)) for x in lines) -gold = best_seqs.most_common(1)[0][1] - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/22/python/pyproject.toml b/2024/22/python/pyproject.toml deleted file mode 100644 index 7bd23d0..0000000 --- a/2024/22/python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name = "aoc-2024-22" -version = "0.1.0" -description = "advent of code 2024-22" -requires-python = ">=3.13" -dependencies = [] -- cgit v1.2.3