@@ -0,0 +1 @@ | |||
🪨 |
@@ -14,6 +14,13 @@ CODE := $(BASE).py | |||
DATA := $(BASE).dat | |||
TEST := $(BASE).dtt | |||
save: | |||
git add . | |||
test `git log -1 --format=%s` == `cat VERSION` \ | |||
&& git commit --amend --reuse-message=head \ | |||
|| git commit -m `cat VERSION` | |||
git log -1 | |||
main: ${TEST} | |||
echo 'test': | |||
cat ${TEST} | docker compose run --rm advent python -u ${CODE} |
@@ -0,0 +1,16 @@ | |||
import itertools | |||
def star_dist(a, b, N): | |||
(xa, xb), (ya, yb) = map(sorted, zip(a, b)) | |||
sx = sum(xa < x < xb for x in xs) | |||
sy = sum(ya < y < yb for y in ys) | |||
return (xb - xa) + (yb - ya) + (N - 1) * (sx + sy) | |||
text = open(0).read() | |||
ys = {i for i, ln in enumerate(text.splitlines()) if set(ln) == {'.'}} | |||
xs = {i for i, ln in enumerate(zip(*text.splitlines())) if set(ln) == {'.'}} | |||
stars = {(x, y) for y, row in enumerate(text.splitlines()) for x, val in enumerate(row) if val == '#'} | |||
print(sum(star_dist(a, b, 2) for a, b in itertools.combinations(stars, 2))) | |||
print(sum(star_dist(a, b, 1_000_000) for a, b in itertools.combinations(stars, 2))) |
@@ -0,0 +1,35 @@ | |||
import functools | |||
import re | |||
@functools.lru_cache(maxsize=None) | |||
def get_combos(pattern, ns): | |||
out = 0 | |||
if not ns: | |||
new = '_' * len(pattern) | |||
if re.fullmatch(pattern, new): | |||
out += 1 | |||
else: | |||
n, *ns = ns | |||
i_max = len(pattern) - sum(ns) - len(ns) - n + 1 | |||
for i in range(i_max): | |||
new = '_' * i + '#' * n + '_' * (len(pattern) > i + n) | |||
if re.fullmatch(pattern[:len(new)], new): | |||
out += get_combos(pattern[len(new):], tuple(ns)) | |||
return out | |||
def combos(line, N=1): | |||
pattern, ns = line.split() | |||
# expand | |||
pattern = '?'.join([pattern] * N) | |||
ns = ','.join([ns] * N) | |||
# parse | |||
pattern = pattern.replace('.', '_').replace('?', '.') | |||
ns = [int(n) for n in ns.split(',')] | |||
return get_combos(pattern, tuple(ns)) | |||
text = open(0).read() | |||
print(sum(combos(line) for line in text.splitlines())) | |||
print(sum(combos(line, 5) for line in text.splitlines())) |