| @@ -0,0 +1,18 @@ | |||
| import re | |||
| def solve(text, digits): | |||
| tot = 0 | |||
| rgx = '(' + '|'.join(digits) + ')' | |||
| rgx = f'(?={rgx})' # allow overlapping matches | |||
| for ln in text.splitlines(): | |||
| ns = [digits.get(s, s) for s in re.findall(rgx, ln)] | |||
| tot += 10 * ns[0] + ns[-1] | |||
| print(tot) | |||
| text = open(0).read() | |||
| xs = {v: k for k, v in enumerate('0123456789')} | |||
| ys = {v: k for k, v in enumerate('zero one two three four five six seven eight nine'.split())} | |||
| solve(text, xs) | |||
| solve(text, xs | ys) | |||
| @@ -0,0 +1,16 @@ | |||
| import math | |||
| import re | |||
| text = open(0).read() | |||
| ans1 = 0 | |||
| ans2 = 0 | |||
| for idx, line in enumerate(text.splitlines(), 1): | |||
| parse = lambda string: {v: int(k) for k, v in re.findall(r'(\d+) (r|g|b)', string)} | |||
| games = [parse(game) for game in re.findall(r'[^:;]+', line)[1:]] | |||
| rgb = [max(game.get(k, 0) for game in games) for k in 'rgb'] | |||
| ans1 += all(qty <= lim for qty, lim in zip(rgb, [12, 13, 14])) and idx | |||
| ans2 += math.prod(rgb) | |||
| print(ans1) | |||
| print(ans2) | |||
| @@ -0,0 +1,32 @@ | |||
| import math | |||
| import collections | |||
| import itertools | |||
| import re | |||
| text = open(0).read() | |||
| grid = collections.defaultdict(str) | { | |||
| (x, y): cell | |||
| for y, line in enumerate(text.splitlines()) | |||
| for x, cell in enumerate(line) | |||
| } | |||
| parts = collections.defaultdict(list) | |||
| ans1 = 0 | |||
| for y, ln in enumerate(text.splitlines()): | |||
| ys = [y - 1, y, y + 1] | |||
| for match in re.finditer(r'\d+', ln): | |||
| N = int(match.group(0)) | |||
| xs = list(range(match.start() - 1, match.end() + 1)) | |||
| sub = {(x, y): grid[x, y] for x in xs for y in ys} | |||
| if set(sub.values()) - set('0123456789\n.'): | |||
| ans1 += N | |||
| for key, value in sub.items(): | |||
| if value == '*': | |||
| parts[key].append(N) | |||
| print(ans1) | |||
| ans2 = sum(math.prod(values) for values in parts.values() if len(values) == 2) | |||
| print(ans2) | |||
| @@ -0,0 +1,13 @@ | |||
| text = open(0).read() | |||
| cards = [] | |||
| for line in text.splitlines(): | |||
| ns, ms = [[int(n) for n in line.strip().split()] for line in line.split(':')[1].split('|')] | |||
| cards.append(len(set(ns) & set(ms))) | |||
| print(sum(2 ** (n - 1) for n in cards if n)) | |||
| counter = [1 for _ in cards] | |||
| for i, n in enumerate(cards): | |||
| for j in range(i + 1, i + 1 + n): | |||
| counter[j] += counter[i] | |||
| print(sum(counter)) | |||
| @@ -0,0 +1,34 @@ | |||
| import itertools | |||
| import pathlib | |||
| import re | |||
| text = open(0).read() | |||
| [seed], *groups = [[[int(n) for n in ln.split()] for ln in group.split(':')[1].strip().splitlines()] for group in text.split('\n\n')] | |||
| def forward(n): | |||
| for group in groups: | |||
| n = next((n + (b - a) for b, a, c in group if a <= n < a + c), n) | |||
| return n | |||
| ans1 = min([forward(n) for n in seed]) | |||
| print(ans1) | |||
| ns = [] | |||
| for group in reversed(groups): | |||
| ns += [n for b, a, c in group for n in [b, b + c - 1]] | |||
| ns = [next((n - (b - a) for b, a, c in group if b <= n < b + c), n) for n in ns] | |||
| ans2 = min(forward(n) for n in ns if any(a <= n < a + b for a, b in zip(seed[::2], seed[1::2]))) | |||
| print(ans2) | |||
| # old method, slow | |||
| def backward(n): | |||
| for group in groups: | |||
| n = next((n - (b - a) for b, a, c in group if b <= n < b + c), n) | |||
| return n | |||
| pairs = [(a, a + b) for a, b in zip(seed[::2], seed[1::2])] | |||
| next(n for n in itertools.count(ans2) if any(a <= backward(n) < a + b for a, b in pairs)) | |||