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