| 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) |
| 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) | |||||
| 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) |
| 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)) |
| 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)) |