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