Advent Of Code 2025 Solution
\(\texttt{Intro}\)
今年怎么变成只有 12 天了 qwq
这是一个从每年 12 月 1 日开始的为期 12 天的编程挑战,每天中午 1 pm 会公布一道题。
每道题会有两个部分,你需要用编程解决每一个部分。
本文会使用 C++,Python 进行编程。
网址:https://adventofcode.com/2025
\(\texttt{Day 1}\)
\(\texttt{Part 1}\)
data = open(0).readlines()
st = 50
res = 0
for it in data:
d, step = it[0], int(it[1:])
if d == "L":
st = (st-step+100)%100
else:
st = (st+step)%100
res += (st == 0)
print(res)
\(\texttt{Part 2}\)
data = open(0).readlines()
st = 50
res = 0
for it in data:
d, step = it[0], int(it[1:])
res += step//100
step = step%100
if d == "L":
if st-step <= 0 and st != 0:
res += 1
st = (st-step+100)%100
else:
if st+step >= 100 and st != 0:
res += 1
st = (st+step)%100
print(res)
\(\texttt{Day 2}\)
\(\texttt{Part 1}\)
s = [list(map(int, i.split('-'))) for i in input().split(',')]
def check(x:int):
x = str(x)
if len(x)&1:
return False
return x[:len(x)//2] == x[len(x)//2:]
res = 0
for (l, r) in s:
for i in range(l, r+1):
if check(i):
res += i
print(res)
\(\texttt{Part 2}\)
s = [list(map(int, i.split('-'))) for i in input().split(',')]
def check(x:int):
x = str(x)
for st in range(1, len(x)):
if len(x)%st:
continue
flag = True
for l in range(st, len(x), st):
flag &= (x[l:l+st] == x[:st])
if flag:
return True
return False
res = 0
for (l, r) in s:
for i in range(l, r+1):
if check(i):
res += i
print(res)
\(\texttt{Day 3}\)
\(\texttt{Part 1}\)
s = [i.strip() for i in open(0).readlines()]
def calc(s):
f = [(ord(s[i]), -i) for i in range(len(s)-1)]
f.sort()
p1 = -f[-1][1]
f = [(ord(s[i]), -i) for i in range(p1+1, len(s))]
f.sort()
p2 = -f[-1][1]
return int(s[p1]+s[p2])
print(sum([calc(i) for i in s]))
\(\texttt{Part 2}\)
s = [i.strip() for i in open(0).readlines()]
def calc(s):
res, lst = "", -1
for i in range(11, -1, -1):
f = [(ord(s[j]), -j) for j in range(lst+1, len(s)-i)]
f.sort()
p = -f[-1][1]
res += s[p]
lst = p
return int(res)
print(sum([calc(i) for i in s]))
\(\texttt{Day 4}\)
\(\texttt{Part 1}\)
s = ['.'+i.strip()+'.' for i in open(0).readlines()]
s.insert(0, '.'*(len(s[0])))
s.append('.'*(len(s[0])))
res = 0
for i in range(1, len(s)-1):
for j in range(1, len(s[i])-1):
t = 0
for k in range(-1, 2):
for l in range(-1, 2):
t += (s[i+k][j+l] == '@')
if t <= 4 and s[i][j] == '@':
res += 1
print(res)
\(\texttt{Part 2}\)
s = ['.'+i.strip()+'.' for i in open(0).readlines()]
s.insert(0, '.'*(len(s[0])))
s.append('.'*(len(s[0])))
def calc():
global tar, s
res = 0
for i in range(1, len(s)-1):
for j in range(1, len(s[i])-1):
t = 0
for k in range(-1, 2):
for l in range(-1, 2):
t += (s[i+k][j+l] == '@')
if t <= 4 and s[i][j] == '@':
res += 1
tar += 1
s[i] = s[i][:j]+'.'+s[i][j+1:]
return res
tar = 0
while calc():
pass
print(tar)
\(\texttt{Day 5}\)
\(\texttt{Part 1}\)
s = ''.join(open(0).readlines())
[r, v] = s.split('\n\n')
seq = [tuple(map(int, i.split('-'))) for i in r.split('\n')]
v = list(map(int, v.split('\n')))
def check(x:int):
for (l, r) in seq:
if l <= x and x <= r:
return True
return False
print(sum(check(i) for i in v))
\(\texttt{Part 2}\)
s = ''.join(open(0).readlines())
[r, v] = s.split('\n\n')
seq = [tuple(map(int, i.split('-'))) for i in r.split('\n')]
seq.sort()
L, R, res = 0, -1, 0
for (l, r) in seq:
if l > R:
res += R-L+1
L, R = l, r
else:
R = max(R, r)
res += R-L+1
print(res)
\(\texttt{Day 6}\)
\(\texttt{Part 1}\)
import re
s = ''.join(open(0).readlines()).split('\n')
s = [re.findall(r'\d+|\+|\*', i) for i in s]
res = 0
for p in range(len(s[0])):
op = s[-1][p]
if op == '+':
res += sum(int(s[i][p]) for i in range(len(s)-1))
else:
v, ss = [s[i][p] for i in range(len(s)-1)], 1
for i in v:
ss *= int(i)
res += ss
print(res)
\(\texttt{Part 2}\)
s = ''.join(open(0).readlines()).split('\n')
v = [''.join([s[j][i] for j in range(len(s)-1)]) for i in range(len(s[0]))]
res, ss, op = 0, 0, ''
for i in range(len(s[0])):
if s[-1][i] != ' ':
op = s[-1][i]
res += ss
ss = 0 if op == '+' else 1
if v[i] != ' '*len(v[i]):
ss = ss*int(v[i]) if op == '*' else ss+int(v[i])
print(res+ss)
\(\texttt{Day 7}\)
\(\texttt{Part 1}\)
s = [i.strip() for i in open(0).readlines()]
p, res = set(), 0
for it in s:
for i in range(len(it)):
if it[i] == 'S':
p.add(i)
elif it[i] == '^':
if i in p:
p.remove(i)
p.add(i-1)
p.add(i+1)
res += 1
print(res)
\(\texttt{Part 2}\)
s = [i.strip() for i in open(0).readlines()]
p = [0]*len(s[0])
for it in s:
for i in range(len(it)):
if it[i] == 'S':
p[i] = 1
elif it[i] == '^':
p[i-1] += p[i]
p[i+1] += p[i]
p[i] = 0
print(sum(p))
\(\texttt{Day 8}\)
\(\texttt{Part 1}\)
import math
p = [list(map(int, i.strip().split(','))) for i in open(0).readlines()]
e, fa, siz = [], [i for i in range(len(p))], [1 for i in range(len(p))]
def find(x:int):
if x == fa[x]:
return x
fa[x] = find(fa[x])
return fa[x]
def merge(x:int, y:int):
x, y = find(x), find(y)
if x == y:
return False
fa[x] = y
siz[y] += siz[x]
return True
for i in range(len(p)):
for j in range(i+1, len(p)):
e.append([math.dist(p[i], p[j]), i, j])
e.sort()
for (d, u, v) in e[:1000]:
merge(u, v)
siz = [siz[i] if fa[i] == i else 0 for i in range(len(siz))]
siz.sort(reverse=True)
print(math.prod(siz[:3]))
\(\texttt{Part 2}\)
import math
p = [list(map(int, i.strip().split(','))) for i in open(0).readlines()]
e, fa, siz = [], [i for i in range(len(p))], [1 for i in range(len(p))]
def find(x:int):
if x == fa[x]:
return x
fa[x] = find(fa[x])
return fa[x]
def merge(x:int, y:int):
x, y = find(x), find(y)
if x == y:
return False
fa[x] = y
siz[y] += siz[x]
return True
for i in range(len(p)):
for j in range(i+1, len(p)):
e.append([math.dist(p[i], p[j]), i, j])
e.sort()
for (d, u, v) in e:
merge(u, v)
if siz[find(1)] == len(p):
print(p[u][0]*p[v][0])
break
\(\texttt{Day 9}\)
\(\texttt{Part 1}\)
s = [tuple(map(int, it.strip().split(','))) for it in open(0).readlines()]
print(max(abs(i[0]-j[0]+1)*abs(i[1]-j[1]+1) for i in s for j in s))
\(\texttt{Part 2}\)
import numpy as np
# input
s = [list(map(int, it.strip().split(','))) for it in open(0).readlines()]
# sort
v = [i[0] for i in s]
v.extend([i[1] for i in s])
v = list(map(int, np.unique(v)))
ex = [0]
for i in range(1, len(v)):
if v[i] != v[i-1]+1:
ex.append(v[i]-1)
v.extend(ex)
v = list(map(int, np.unique(v)))
m = len(v)
# map
mp = dict(zip(v, [i for i in range(m)]))
p = [[mp[i[0]], mp[i[1]]] for i in s]
a = [[0]*len(v) for i in v]
# path
st = [p[-1][0], p[-1][1]]
for it in p:
while st[0] < it[0]:
a[st[0]][st[1]] = 1
st[0] += 1
while st[0] > it[0]:
a[st[0]][st[1]] = 1
st[0] -= 1
while st[1] < it[1]:
a[st[0]][st[1]] = 1
st[1] += 1
while st[1] > it[1]:
a[st[0]][st[1]] = 1
st[1] -= 1
# flood fill
q, a[0][0] = [[0, 0]], 2
while len(q):
now = q[0]
q = q[1:]
for (dx, dy) in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
if a[now[0]+dx][now[1]+dy] == 0:
a[now[0]+dx][now[1]+dy] = 2
q.append([now[0]+dx, now[1]+dy])
# 2d prefix sum
for i in range(m):
for j in range(m):
a[i][j] = (a[i][j] != 2)
if i > 0:
a[i][j] += a[i-1][j]
if j > 0:
a[i][j] += a[i][j-1]
if i > 0 and j > 0:
a[i][j] -= a[i-1][j-1]
# check
res = 0
for (x0, y0) in s:
for (x1, y1) in s:
sx, ex, sy, ey = min(x0, x1), max(x0, x1), min(y0, y1), max(y0, y1)
ssx, ssy, eex, eey = mp[sx], mp[sy], mp[ex], mp[ey]
ss, sss = (ex-sx+1)*(ey-sy+1), (eex-ssx+1)*(eey-ssy+1)
if a[eex][eey]-a[ssx-1][eey]-a[eex][ssy-1]+a[ssx-1][ssy-1] == sss:
res = max(res, ss)
print(res)
\(\texttt{Day 10}\)
\(\texttt{Part 1}\)
from functools import reduce
import re
s = [it.strip() for it in open(0).readlines()]
t = 0
for it in s:
it = it.split()
req = [sum(2**int(j) for j in re.findall(r'\d+', i)) for i in it[1:-1]]
x = int(it[0][::-1][1:-1].replace('.','0').replace('#','1'), 2)
res = 1e18
for i in range(1, 2**len(req)):
nw = [req[p] for p in range(len(req)) if (i>>p)&1]
y = reduce(lambda x, y: x^y, nw)
if x == y:
res = min(res, bin(i).count('1'))
t += res
print(t)
\(\texttt{Part 2}\)
z3 大法好!
什么整数线性规划,跟我的 z3 说去吧!
运行报错的,检查你有没有安装 z3-solver 库。
import z3
import re
s = [it.strip() for it in open(0).readlines()]
t = 0
for it in s:
it = it.split()
req = [sum(2**int(j) for j in re.findall(r'\d+', i)) for i in it[1:-1]]
x = eval(f"[{it[-1][1:-1]}]")
sol = z3.Optimize()
v = [z3.Int(f'x{i}') for i in range(len(req))]
for it in v:
sol.add(it >= 0)
for i in range(len(x)):
l = sum(((req[j]>>i)&1)*v[j] for j in range(len(v)))
sol.add(l == x[i])
sol.minimize(z3.Sum(v))
if sol.check() == z3.sat:
m = sol.model()
t += sum(m[it] for it in v)
print(z3.simplify(t))
\(\texttt{Day 11}\)
\(\texttt{Part 1}\)
import math
import re
s = [re.findall(r'\w+', it.strip()) for it in open(0).readlines()]
d, e, f = dict(), dict(), dict()
for i in s:
e[i[0]] = i[1:]
for it in i:
if it not in d:
d[it] = 0
d[it] += (it != i[0])
f[it] = int(it == 'you')
q = list(filter(lambda it: not d[it], d))
while len(q):
now = q[0]
q = q[1:]
if now in e:
for it in e[now]:
d[it] -= 1
f[it] += f[now]
if not d[it]:
q.append(it)
print(f['out'])
\(\texttt{Part 2}\)
import math
import re
s = [re.findall(r'\w+', it.strip()) for it in open(0).readlines()]
t = 0
def calc(st, ed):
d, e, f = dict(), dict(), dict()
for i in s:
e[i[0]] = i[1:]
for it in i:
if it not in d:
d[it] = 0
d[it] += (it != i[0])
f[it] = int(it == st)
q = list(filter(lambda it: not d[it], d))
while len(q):
now = q[0]
q = q[1:]
if now in e:
for it in e[now]:
d[it] -= 1
f[it] += f[now]
if not d[it]:
q.append(it)
return f[ed]
t += calc('svr', 'dac')*calc('dac', 'fft')*calc('fft', 'out')
t += calc('svr', 'fft')*calc('fft', 'dac')*calc('dac', 'out')
print(t)
\(\texttt{Day 12}\)
\(\texttt{Part 1 & Part 2}\)
发现样例的拼图要么很多要么少一个量级。
大胆猜测直接判断拼图面积是否小于地图面积即可。
虽然这个连样例都过不去。
如果想要确定的解的话请学习 Dancing Link 算法。
import re
s = ''.join(open(0).readlines()).split('\n\n')
s = [i.strip().split('\n') for i in s]
for i in range(len(s)-1):
s[i] = ''.join(s[i]).count('#')
s[-1] = [re.findall(r'\d+', it) for it in s[-1]]
res = 0
for it in s[-1]:
n, m, tot = int(it[0]), int(it[1]), 0
for i in range(len(s)-1):
tot += int(it[i+2])*s[i]
res += (tot <= n*m)
print(res)

浙公网安备 33010602011771号