From 14354c85b8922c5b07b6a4ccc9e67d2958ecc78b Mon Sep 17 00:00:00 2001 From: Sijmen Date: Fri, 29 Dec 2023 22:03:50 +0100 Subject: [PATCH] Catch up to day 15 --- .gitignore | 3 ++ day09.py | 25 +++++++++ day10.py | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++ day11.py | 76 ++++++++++++++++++++++++++ day12.py | 34 ++++++++++++ day13.py | 47 ++++++++++++++++ day15.py | 47 ++++++++++++++++ empty.py | 2 + template.py | 15 ++++++ 9 files changed, 400 insertions(+) create mode 100644 day09.py create mode 100644 day10.py create mode 100644 day11.py create mode 100644 day12.py create mode 100644 day13.py create mode 100644 day15.py create mode 100644 empty.py create mode 100644 template.py 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()