diff --git a/.gitignore b/.gitignore index 3fad632..68b5804 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ *.in *.ex* day?? + +*.prof +*.lprof diff --git a/day09.py b/day09.py new file mode 100644 index 0000000..efd448c --- /dev/null +++ b/day09.py @@ -0,0 +1,25 @@ +import fileinput +from collections import deque + +def main(): + part1 = 0 + part2 = 0 + + for line in fileinput.input(): + values = deque(int(t) for t in line.split()) + + stack = [values] + while any(values): + values = deque(values[i + 1] - values[i] for i in range(len(values) - 1)) + stack.append(values) + + for i in range(len(stack) - 1, 0, -1): + stack[i - 1].append(stack[i - 1][-1] + stack[i][-1]) + stack[i - 1].appendleft(stack[i - 1][0] - stack[i][0]) + + part1 += stack[0][-1] + part2 += stack[0][0] + + print(part1, part2) + +main() diff --git a/day10.py b/day10.py new file mode 100644 index 0000000..6dbda21 --- /dev/null +++ b/day10.py @@ -0,0 +1,151 @@ +from collections import deque +import fileinput +from pprint import pprint +from dataclasses import dataclass + +map = [] + +(sx, sy) = (0, 0) +for (j, line) in enumerate(fileinput.input()): + map.append(list(line.strip())) + if (x := line.find("S")) != -1: + (sx, sy) = (x, j) + +seen = set() +queue: deque[tuple[int, int, int]] = deque([(sx, sy, 0)]) +distances = [[None] * len(map[0]) for _ in range(len(map))] + +NS = "|" +WE = "-" +NE = "L" +NW = "J" +SW = "7" +SE = "F" + +part1 = 0 +while queue: + (x, y, l) = queue.popleft() + if (x, y) in seen: + continue + + seen.add((x, y)) + distances[y][x] = l + part1 = l + + match map[y][x]: + case "S": + if map[y - 1][x] in "|7F": + queue.append((x, y - 1, l + 1)) + if map[y + 1][x] in "|LJ": + queue.append((x, y + 1, l + 1)) + if map[y][x - 1] in "-LF": + queue.append((x - 1, y, l + 1)) + if map[y][x + 1] in "-J7": + queue.append((x + 1, y, l + 1)) + case "|": + queue.append((x, y - 1, l + 1)) + queue.append((x, y + 1, l + 1)) + case "-": + queue.append((x - 1, y, l + 1)) + queue.append((x + 1, y, l + 1)) + case "L": + queue.append((x + 1, y, l + 1)) + queue.append((x, y - 1, l + 1)) + case "J": + queue.append((x - 1, y, l + 1)) + queue.append((x, y - 1, l + 1)) + case "7": + queue.append((x - 1, y, l + 1)) + queue.append((x, y + 1, l + 1)) + case "F": + queue.append((x + 1, y, l + 1)) + queue.append((x, y + 1, l + 1)) + +part1 = 0 +for l in distances: + part1 = max(part1, 0, *[i for i in l if i]) +print(part1) + +side = set() +for y in range(len(map)): + if map[y][0] == ".": side.add((0, y)) + if map[y][-1] == ".": side.add((len(map[0]) - 1, y)) +for x in range(len(map[0])): + if map[0][x] == ".": side.add((x, 0)) + if map[-1][x] == ".": side.add((x, len(map) - 1)) + +mapp = [] +for (x, row) in enumerate(map): + r = [] + for (y, c) in enumerate(row): + match c: + case ".": + r.append(["..."]*3) + case "S": + r.append([".X.","XXX",".X."]) + case "-": + r.append(["...","XXX","..."]) + case "|": + r.append([".X.",".X.",".X."]) + case "7": + r.append(["...","XX.",".X."]) + case "F": + r.append(["...",".XX",".X."]) + case "J": + r.append([".X.","XX.","..."]) + case "L": + r.append([".X.",".XX","..."]) + mapp.append(r) + +bigmap = [] +for row in mapp: + for y in range(3): + r = [] + for col in row: + for x in range(3): + r.append(col[y][x]) + bigmap.append(r) + print(r) + +exterior = [] +for y in range(len(bigmap)): + if bigmap[y][0] == ".": + exterior.append((0, y)) + if bigmap[y][-1] == ".": + exterior.append((len(bigmap[0]) - 1, y)) + + +for x in range(len(bigmap[0])): + if bigmap[0][x] == ".": + exterior.append((x, 0)) + if bigmap[-1][x] == ".": + exterior.append((x, len(bigmap) - 1)) + +for (x, y) in exterior: + if y < 0 or y > len(bigmap) - 1: + continue + if x < 0 or x > len(bigmap[y]) - 1: + continue + if bigmap[y][x] != ".": + continue + + bigmap[y][x] = "O" + + exterior.append((x - 1, y)) + exterior.append((x + 1, y)) + exterior.append((x, y - 1)) + exterior.append((x, y + 1)) + +for row in distances: + for c in row: + print("X" if c is not None else ".", end="") + print() + +part2 = 0 +for y in range(1, len(bigmap), 3): + for x in range(1, len(bigmap[y]), 3): + if bigmap[y][x] == "." or (distances[y // 3][x // 3] is None): + part2 += 1 + map[y//3][x//3] = 'I' + +print(part1, part2) diff --git a/day11.py b/day11.py new file mode 100644 index 0000000..36e1b8a --- /dev/null +++ b/day11.py @@ -0,0 +1,76 @@ +import fileinput +import math +from pprint import pprint +from itertools import pairwise + +def main(): + (part1, part2) = (0, 0) + + # parse + inp = fileinput.input() + coords_ = [] + (w, h) = (0, 0) + for (y, row) in enumerate(inp): + for (x, c) in enumerate(row): + if c == "#": + coords_.append((x, y)) + w = max(w, x) + h = max(h, y) + + coords = coords_.copy() + + (dx, dy) = (0, 0) + for j in range(h): + if not any(y_ == j + dy for (_, y_) in coords): + print(f"inserting row at y={j}") + for i in range(len(coords)): + (x_, y_) = coords[i] + if y_ > j + dy: + coords[i] = (x_, y_ + 1) + dy += 1 + if not any(x_ == j + dx for (x_, _) in coords): + print(f"inserting column at x={j}") + for i in range(len(coords)): + (x_, y_) = coords[i] + if x_ > j + dx: + coords[i] = (x_ + 1, y_) + dx += 1 + + part1 = 0 + for ai in range(len(coords)): + for bi in range(ai + 1, len(coords)): + (ax, ay) = coords[ai] + (bx, by) = coords[bi] + part1 += abs(ax - bx) + abs(ay - by) + + coords = coords_.copy() + L = 1_000_000 - 1 + + (dx, dy) = (0, 0) + for j in range(h): + if not any(y_ == j + dy for (_, y_) in coords): + print(f"inserting rows at y={j}") + for i in range(len(coords)): + (x_, y_) = coords[i] + if y_ > j + dy: + coords[i] = (x_, y_ + L) + dy += L + if not any(x_ == j + dx for (x_, _) in coords): + print(f"inserting columns at x={j}") + for i in range(len(coords)): + (x_, y_) = coords[i] + if x_ > j + dx: + coords[i] = (x_ + L, y_) + dx += L + + part2 = 0 + for ai in range(len(coords)): + for bi in range(ai + 1, len(coords)): + (ax, ay) = coords[ai] + (bx, by) = coords[bi] + part2 += abs(ax - bx) + abs(ay - by) + + print(part1, part2) + +if __name__ == "__main__": + main() diff --git a/day12.py b/day12.py new file mode 100644 index 0000000..eeda91d --- /dev/null +++ b/day12.py @@ -0,0 +1,34 @@ +import fileinput +import math +from pprint import pprint +from itertools import chain, combinations, count, groupby +import re + +RE = re.compile(r"[#\?]") + +def powerset(iterable): + "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" + s = list(iterable) + return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) + +def main(): + (part1, part2) = (0, 0) + + inp = fileinput.input() + for line in inp: + (springs, groups) = line.split() + groups = [int(g) for g in groups.split(",")] + + unknowns = [x for (x, c) in enumerate(springs) if c == "?"] + springs_ = springs.replace("?", ".") + for xs in powerset(unknowns): + h = "".join("#" if i in xs else c for (i, c) in enumerate(springs_)) + match = [len(g) for g in RE.findall(h)] + if match == groups: + part1 += 1 + + + print(part1, part2) + +if __name__ == "__main__": + main() diff --git a/day13.py b/day13.py new file mode 100644 index 0000000..9d9038d --- /dev/null +++ b/day13.py @@ -0,0 +1,47 @@ +import sys +import numpy as np + + +# @profile +def main(): + with open(sys.argv[1]) as f: + inp = [ + [[c == "#" for c in line] for line in field.split("\n")] + for field in f.read().strip().split("\n\n") + ] + + (part1, part2) = (0, 0) + + for field in inp: + field = np.array(field) + (h, w) = field.shape + + (x1, y1, x2, y2) = (0, 0, 0, 0) + for x in range(1, w): + w2 = min(x, w - x) + left = field[:, (x - w2) : x] + right = field[:, x : (x + w2)][:, ::-1] + mismatches = (left != right).sum() + if not x2 and mismatches == 1: + x2 = x + elif not x1 and mismatches == 0: + x1 = x + + if not x1 or not x2: + for y in range(1, h): + h2 = min(y, h - y) + left = field[(y - h2) : y] + right = field[y : (y + h2)][::-1] + mismatches = (left != right).sum() + if not y2 and mismatches == 1: + y2 = y + elif not y1 and mismatches == 0: + y1 = y + + part1 += x1 + y1 * 100 + part2 += x2 + y2 * 100 + + print(part1, part2) + + +main() diff --git a/day15.py b/day15.py new file mode 100644 index 0000000..35834a7 --- /dev/null +++ b/day15.py @@ -0,0 +1,47 @@ +import os +import sys +from collections import defaultdict + +def hash(s): + v = 0 + for c in s: + if c == ",": + continue + v += ord(c) + v *= 17 + v %= 256 + return v + +with open(sys.argv[1]) as f: + s = f.read().strip() + +boxes = defaultdict(list) + +part1 = 0 +for s_ in s.split(","): + part1 += hash(s_) + + if s_[-1] == "-": + label = s_[:-1] + h = hash(label) + for i in range(len(boxes[h])): + if boxes[h][i][0] == label: + del boxes[h][i] + break + elif s_[-2] == "=": + label = s_[:-2] + focal = int(s_[-1]) + h = hash(label) + for i in range(len(boxes[h])): + if boxes[h][i][0] == label: + boxes[h][i] = (label, focal) + break + else: + boxes[h].append((label, focal)) + +part2 = 0 +for (box_i, box) in boxes.items(): + for (slot, (_, focal)) in enumerate(box): + part2 += (box_i + 1) * (slot + 1) * focal + +print(part1, part2) diff --git a/empty.py b/empty.py new file mode 100644 index 0000000..5420848 --- /dev/null +++ b/empty.py @@ -0,0 +1,2 @@ +import fileinput +list(fileinput.input()) diff --git a/template.py b/template.py new file mode 100644 index 0000000..eb710ba --- /dev/null +++ b/template.py @@ -0,0 +1,15 @@ +import fileinput +import math +from pprint import pprint + +def main(): + (part1, part2) = (0, 0) + + inp = fileinput.input() + for line in inp: + pass + + print(part1, part2) + +if __name__ == "__main__": + main()