Advent Of Code 2022 Solution
\(\texttt{Intro}\)
这是一个从每年 12 月 1 日开始的为期 25 天的编程挑战,每天中午 1 pm 会公布一道题。
每道题会有两个部分,你需要用编程解决每一个部分。
本文会使用 C++,Python 进行编程。
网址:https://adventofcode.com/2022
\(\texttt{Day 1}\)
\(\texttt{Part 1}\)
a=list(map(lambda it:sum(map(int,it.split('\n'))),''.join(open(0).readlines()).split('\n\n')))
print(max(a))
\(\texttt{Part 2}\)
a=list(map(lambda it:sum(map(int,it.split('\n'))),''.join(open(0).readlines()).split('\n\n')))
a.sort()
print(sum(a[-3:]))
\(\texttt{Day 2}\)
\(\texttt{Part 1}\)
win,draw=["AY","BZ","CX"],["AX","BY","CZ"]
a=list(map(lambda it:it[0]+it[2],open(0).readlines()))
tar=sum(win.count(i)*6+draw.count(i)*3 for i in a)
tar+=sum("XYZ".index(i[1])+1 for i in a)
print(tar)
\(\texttt{Part 2}\)
a=list(map(lambda it:it[0]+it[2],open(0).readlines()))
tar=sum(("ABC".index(i[0])+(i[1]=="Z")-(i[1]=="X")+3)%3+1 for i in a)
tar+=sum((i[1]=="Z")*6+(i[1]=="Y")*3 for i in a)
print(tar)
\(\texttt{Day 3}\)
\(\texttt{Part 1}\)
def val(x): return (ord(x)-96 if ord(x)>96 else ord(x)-38)
a=list(map(lambda it:it.strip(),open(0).readlines()))
print(sum(val(str(set(it[:len(it)//2])&set(it[len(it)//2:]))[2]) for it in a))
\(\texttt{Part 2}\)
def val(x): return (ord(x)-96 if ord(x)>96 else ord(x)-38)
a=list(map(lambda it:it.strip(),open(0).readlines()))
print(sum(val(str(set(a[it])&set(a[it+1])&set(a[it+2]))[2]) for it in range(0,len(a),3)))
\(\texttt{Day 4}\)
\(\texttt{Part 1}\)
tar,a=0,list(map(lambda it:list(map(lambda it:list(map(int,it.split('-'))),it.strip().split(','))),open(0).readlines()))
tar+=sum(i[0][0]<=i[1][0] and i[0][1]>=i[1][1] for i in a)
tar+=sum(i[0][0]>=i[1][0] and i[0][1]<=i[1][1] for i in a)
tar-=sum(i[0][0]==i[1][0] and i[0][1]==i[1][1] for i in a)
print(tar)
\(\texttt{Part 2}\)
tar,a=0,list(map(lambda it:list(map(lambda it:list(map(int,it.split('-'))),it.strip().split(','))),open(0).readlines()))
a=map(lambda it:(max(it[0][0],it[1][0]),min(it[0][1],it[1][1])),a)
print(sum(it[0]<=it[1] for it in a))
\(\texttt{Day 5}\)
\(\texttt{Part 1}\)
import re
a,b=''.join(open(0).readlines()).split('\n\n')
a,b=a.split('\n'),list(map(lambda it:list(map(int,re.findall(r'\d+',it))),b.split('\n')))
n=len(re.findall(r'\d',a[-1]))
a,c=a[:-1][::-1],[]
for i in ' '*n: c.append([])
for l in a:
for i in range(n):
if l[4*i+1]!=' ':
c[i].append(l[4*i+1])
for cnt,f,t in b:
for _ in ' '*cnt:
c[t-1].append(c[f-1][-1])
c[f-1]=c[f-1][:-1]
print(''.join(map(lambda it:it[-1],c)))
\(\texttt{Part 2}\)
import re
a,b=''.join(open(0).readlines()).split('\n\n')
a,b=a.split('\n'),list(map(lambda it:list(map(int,re.findall(r'\d+',it))),b.split('\n')))
n=len(re.findall(r'\d',a[-1]))
a,c=a[:-1][::-1],[]
for i in ' '*n: c.append([])
for l in a:
for i in range(n):
if l[4*i+1]!=' ':
c[i].append(l[4*i+1])
for cnt,f,t in b:
c[t-1]+=c[f-1][len(c[f-1])-cnt:]
c[f-1]=c[f-1][:len(c[f-1])-cnt]
print(''.join(map(lambda it:it[-1],c)))
\(\texttt{Day 6}\)
\(\texttt{Part 1}\)
a=input()
flag=True
for i in range(3,len(a)):
fl=True
for l in range(i-3,i+1):
for r in range(l+1,i+1):
if a[l]==a[r]: fl=False
if fl and flag:
print(i+1)
flag=False
\(\texttt{Part 2}\)
a=input()
flag=True
for i in range(13,len(a)):
fl=True
for l in range(i-13,i+1):
for r in range(l+1,i+1):
if a[l]==a[r]: fl=False
if fl and flag:
print(i+1)
flag=False
\(\texttt{Day 7}\)
\(\texttt{Part 1}\)
a=list(map(lambda it:it.strip().split(),open(0).readlines()))
dir,road,lines,tar=[],{},[],0
for it in a:
if it[0]=='$':
if it[1]=='cd':
if it[2]=='..': dir=dir[:-1]
elif it[2]=='/': dir=['/']
else:
if (str(dir),str(dir+[it[2]])) not in lines:
lines.append((str(dir),str(dir+[it[2]])))
dir.append(it[2])
elif it[1]=='ls':
pass
else:
if it[0]=='dir':
if (str(dir),str(dir+[it[1]])) not in lines:
lines.append((str(dir),str(dir+[it[1]])))
else:
lines.append((str(dir),it[0]))
def dfs(root):
global tar
siz=0
for f,t in lines:
if f!=root: continue
if t[0]!='[': siz+=int(t)
else: siz+=dfs(t)
if siz<=100000: tar+=siz
return siz
dfs(str(['/']))
print(tar)
\(\texttt{Part 2}\)
a=list(map(lambda it:it.strip().split(),open(0).readlines()))
dir,road,lines,tar,lim=[],{},[],0,-1
for it in a:
if it[0]=='$':
if it[1]=='cd':
if it[2]=='..': dir=dir[:-1]
elif it[2]=='/': dir=['/']
else:
if (str(dir),str(dir+[it[2]])) not in lines:
lines.append((str(dir),str(dir+[it[2]])))
dir.append(it[2])
elif it[1]=='ls':
pass
else:
if it[0]=='dir':
if (str(dir),str(dir+[it[1]])) not in lines:
lines.append((str(dir),str(dir+[it[1]])))
else:
lines.append((str(dir),it[0]))
def dfs(root):
global tar,lim
siz=0
for f,t in lines:
if f!=root: continue
if t[0]!='[': siz+=int(t)
else: siz+=dfs(t)
if lim==-1:
if siz<=100000: tar+=siz
else:
if siz>=lim: tar=min(tar,siz)
return siz
tot=dfs(str(['/']))
tar,lim=1e18,30000000-(70000000-tot)
dfs(str(['/']))
print(tar)
\(\texttt{Day 8}\)
\(\texttt{Part 1}\)
a=list(map(lambda it:[int(i) for i in it.strip()],open(0).readlines()))
vis=[[False for _ in i] for i in a]
n,m=len(a),len(a[0])
for i in range(0,n):
mx=-1
for j in range(0,m):
if a[i][j]>mx: mx,vis[i][j]=a[i][j],True
mx=-1
for j in range(m-1,-1,-1):
if a[i][j]>mx: mx,vis[i][j]=a[i][j],True
for j in range(0,m):
mx=-1
for i in range(0,n):
if a[i][j]>mx: mx,vis[i][j]=a[i][j],True
mx=-1
for i in range(n-1,-1,-1):
if a[i][j]>mx: mx,vis[i][j]=a[i][j],True
print(sum(sum(i) for i in vis))
\(\texttt{Part 2}\)
def calc(x:int,y:int):
tar=1
mx,sum=a[x][y],0
for j in range(y+1,m):
if a[x][j]<mx: sum+=1
else:
sum+=1
break
tar*=sum
mx,sum=a[x][y],0
for j in range(y-1,-1,-1):
if a[x][j]<mx: sum+=1
else:
sum+=1
break
tar*=sum
mx,sum=a[x][y],0
for i in range(x+1,n):
if a[i][y]<mx: sum+=1
else:
sum+=1
break
tar*=sum
mx,sum=a[x][y],0
for i in range(x-1,-1,-1):
if a[i][y]<mx: sum+=1
else:
sum+=1
break
tar*=sum
return tar
a=list(map(lambda it:[int(i) for i in it.strip()],open(0).readlines()))
n,m=len(a),len(a[0])
print(max(max(calc(i,j) for j in range(len(a[i]))) for i in range(len(a))))
# print('\n'.join([str([calc(i,j) for j in range(len(a[i]))]) for i in range(len(a))]))
\(\texttt{Day 9}\)
\(\texttt{Part 1}\)
a=[(i[0],int(i[1])) for i in [i.strip().split(' ') for i in open(0).readlines()]]
dx,dy=[1,-1,0,0],[0,0,-1,1] # UDLR
s,t,route=(0,0),(0,0),set([(0,0)])
for p,q in a:
for _ in ' '*q:
lst,s=s,(s[0]+dx["UDLR".index(p)],s[1]+dy["UDLR".index(p)])
if max(abs(s[0]-t[0]),abs(s[1]-t[1]))>1: t=lst
route.add(t)
print(len(route))
\(\texttt{Part 2}\)
def sgn(x): return (0 if not x else (-1 if x<0 else 1))
def nxt(s,t):
dis=max(abs(s[0]-t[0]),abs(s[1]-t[1]))
return (t[0]+sgn(s[0]-t[0])*(dis>1),t[1]+sgn(s[1]-t[1])*(dis>1))
a=[(i[0],int(i[1])) for i in [i.strip().split(' ') for i in open(0).readlines()]]
dx,dy=[1,-1,0,0],[0,0,-1,1] # UDLR
s,route=[(0,0)]*10,set([(0,0)])
for p,q in a:
for _ in ' '*q:
s[0]=(s[0][0]+dx["UDLR".index(p)],s[0][1]+dy["UDLR".index(p)])
for i in range(1,10): s[i]=nxt(s[i-1],s[i])
route.add(s[9])
print(len(route))
\(\texttt{Day 10}\)
\(\texttt{Part 1}\)
a=[i.strip().split() for i in open(0).readlines()]
r,v,tar,dt=0,1,0,0
for it in a:
l1,l2=r,v
if it[0]=='noop': r+=1
else: r+=2
if l1%40<20 and r%40>=20: tar+=l2*(l1//40*40+20)
if it[0]!='noop': v+=int(it[1])
print(tar)
\(\texttt{Part 2}\)
def work():
global t
print(("#" if l<=t%40 and t%40<l+3 else '.'),end=('\n' if t%40==39 else ''))
t+=1
a=[i.strip().split() for i in open(0).readlines()]
t,l=0,0
for it in a:
if it[0]=='noop': work()
else: work(),work()
if it[0]!='noop': l+=int(it[1])
\(\texttt{Day 11}\)
\(\texttt{Part 1}\)
import re
def work():
global tot
for it in range(len(b)):
for i in b[it][1]:
old=i
old=eval(b[it][2])
old//=3
b[b[it][4][0] if old%b[it][3][0]==0 else b[it][5][0]][1].append(old)
tot[it]+=len(b[it][1])
b[it][1]=[]
s=open(0).readlines()
a,b,tot=[[int(it) for it in re.findall(r"\d+",i)] for i in s],[],[]
for i in range(0,len(a),7):
b.append(a[i:i+7])
b[-1][2]=s[i+2].split(' = ')[1].strip()
tot.append(0)
for i in ' '*20: work()
tot.sort()
print(tot[-1]*tot[-2])
\(\texttt{Part 2}\)
import re
def nxt(pos: int, old: int):
global tot
tot[pos] += 1
old = b[pos][2](old)//3
pos = b[pos][4][0] if old%b[pos][3][0] == 0 else b[pos][5][0]
return (pos, old)
s = open(0).readlines()
a, b, tot = [[int(it) for it in re.findall(r"\d+",i)] for i in s], [], []
lcm = 1
for i in range(0, len(a), 7):
b.append(a[i:i+7])
b[-1][2] = eval("lambda old: "+s[i+2].split(' = ')[1].strip())
lcm = lcm*b[-1][3][0]
tot.append(0)
for i in range(len(b)):
for it in b[i][1]:
pos, num = i, it
turn = 1
while turn <= 10000:
(pos2, num2) = nxt(pos, num)
if pos > pos2:
turn += 1
pos, num = pos2, num2%lcm
print(tot[-1]*tot[-2])
\(\texttt{Day 12}\)
\(\texttt{Part 1}\)
s = [list(i.strip()) for i in open(0).readlines()]
f = [[1e18 for _ in i] for i in s]
st, ed = (0, 0), (0, 0)
for i in range(len(s)):
for j in range(len(s[i])):
if s[i][j] == 'S':
st = (i, j)
f[i][j] = 0
s[i][j] = 'a'
if s[i][j] == 'E':
ed = (i, j)
s[i][j] = 'z'
q = [st]
while len(q):
(x, y) = q[0]
q = q[1:]
for (dx, dy) in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
if x+dx<0 or x+dx>=len(s) or y+dy<0 or y+dy>=len(s[0]):
continue
if ord(s[x+dx][y+dy])-ord(s[x][y])>1:
continue
if f[x+dx][y+dy] <= f[x][y]+1:
continue
f[x+dx][y+dy] = f[x][y]+1
q.append((x+dx, y+dy))
print(f[ed[0]][ed[1]])
\(\texttt{Part 2}\)
s = [list(i.strip()) for i in open(0).readlines()]
f = [[1e18 for _ in i] for i in s]
ed = (0, 0)
q = []
for i in range(len(s)):
for j in range(len(s[i])):
if s[i][j] == 'S' or s[i][j] == 'a':
f[i][j] = 0
s[i][j] = 'a'
q.append((i, j))
if s[i][j] == 'E':
ed = (i, j)
s[i][j] = 'z'
while len(q):
(x, y) = q[0]
q = q[1:]
for (dx, dy) in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
if x+dx<0 or x+dx>=len(s) or y+dy<0 or y+dy>=len(s[0]):
continue
if ord(s[x+dx][y+dy])-ord(s[x][y])>1:
continue
if f[x+dx][y+dy] <= f[x][y]+1:
continue
f[x+dx][y+dy] = f[x][y]+1
q.append((x+dx, y+dy))
print(f[ed[0]][ed[1]])
\(\texttt{Day 13}\)
\(\texttt{Part 1}\)
s = ''.join(open(0).readlines()).split('\n\n')
s = [[eval(j.strip()) for j in i.split('\n')] for i in s]
def cp(x, y):
if type(x) == int and type(y) == int:
return -1 if x < y else 0 if x == y else x > y
if type(x) == int:
x = [x]
if type(y) == int:
y = [y]
if not len(x) or not len(y):
x, y = len(x), len(y)
return -1 if x < y else 0 if x == y else x > y
s = cp(x[0], y[0])
if s != 0:
return s
return cp(x[1:], y[1:])
res = 0
for i in range(len(s)):
if cp(s[i][0], s[i][1]) == -1:
res += i+1
print(res)
\(\texttt{Part 2}\)
from functools import cmp_to_key
s = ''.join(open(0).readlines()).replace('\n\n','\n')
s = [eval(j.strip()) for j in s.split('\n')]
def cp(x, y):
if type(x) == int and type(y) == int:
return -1 if x < y else 0 if x == y else x > y
if type(x) == int:
x = [x]
if type(y) == int:
y = [y]
if not len(x) or not len(y):
x, y = len(x), len(y)
return -1 if x < y else 0 if x == y else x > y
s = cp(x[0], y[0])
if s != 0:
return s
return cp(x[1:], y[1:])
s.append([[2]])
s.append([[6]])
s.sort(key=cmp_to_key(cp))
res = 1
for i in range(len(s)):
if s[i] == [[2]] or s[i] == [[6]]:
res *= (i+1)
print(res)
\(\texttt{Day 14}\)
\(\texttt{Part 1}\)
s = [[tuple(map(int, j.split(','))) for j in i.strip().split(' -> ')] for i in open(0).readlines()]
def check():
global blk
x, y = 500, 0
while y <= 500:
if (x, y+1) not in blk:
y = y+1
elif (x-1, y+1) not in blk:
x, y = x-1, y+1
elif (x+1, y+1) not in blk:
x, y = x+1, y+1
else:
blk.add((x, y))
return True
return False
res = 0
blk = set()
for it in s:
(x, y) = it[0]
for i in it[1:]:
while x < i[0]:
blk.add((x, y))
x += 1
while x > i[0]:
blk.add((x, y))
x -= 1
while y < i[1]:
blk.add((x, y))
y += 1
while y > i[1]:
blk.add((x, y))
y -= 1
blk.add((x, y))
while check():
res += 1
print(res)
\(\texttt{Part 2}\)
s = [[tuple(map(int, j.split(','))) for j in i.strip().split(' -> ')] for i in open(0).readlines()]
def check():
global blk
x, y = 500, 0
if (x, y) in blk:
return False
while True:
if (x, y+1) not in blk:
y = y+1
elif (x-1, y+1) not in blk:
x, y = x-1, y+1
elif (x+1, y+1) not in blk:
x, y = x+1, y+1
else:
blk.add((x, y))
return True
res = 0
blk = set()
mx = 0
for it in s:
(x, y) = it[0]
mx = max(mx, y)
for i in it[1:]:
while x < i[0]:
blk.add((x, y))
x += 1
while x > i[0]:
blk.add((x, y))
x -= 1
while y < i[1]:
blk.add((x, y))
y += 1
while y > i[1]:
blk.add((x, y))
y -= 1
mx = max(mx, i[1])
blk.add((x, y))
for i in range(-1000, 12000):
blk.add((i, mx+2))
while check():
res += 1
print(res)
\(\texttt{Day 15}\)
\(\texttt{Part 1}\)
import re
s = [list(map(int, re.findall(r'-?\d+', i))) for i in open(0).readlines()]
seq, pt = [], set()
y = 2000000
for (sx, sy, ex, ey) in s:
if sy == y:
pt.add((sx, sy))
if ey == y:
pt.add((ex, ey))
d = abs(ex-sx)+abs(ey-sy)
if abs(sy-y) <= d:
ex = d-abs(sy-y)
seq.append([sx-ex, sx+ex])
seq.sort()
l, r, res = -2147483647, -2147483648, 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-len(pt))
\(\texttt{Part 2}\)
#include <bits/stdc++.h>
using namespace std;
#define fir(x) (get<0>(x))
#define sec(x) (get<1>(x))
#define pb emplace_back
#define mp make_pair
vector<pair<pii,pii>> s;
int check(int x,int y)
{
vector<pii> seq;
for(auto [st,ed]:s)
{
int d=abs(fir(st)-fir(ed))+abs(sec(st)-sec(ed));
if(abs(sec(st)-y)>d) continue;
int ex=d-abs(sec(st)-y);
seq.pb(fir(st)-ex,fir(st)+ex);
}
seq.pb(x+1,x+1);
sort(seq.begin(),seq.end());
int r=0;
// for(auto [L,R]:seq) cerr<<"check "<<y<<' '<<L<<' '<<R<<'\n';
for(auto [L,R]:seq)
{
if(L>r+1) return r+1;
r=max(r,R); if(r>x) break;
}
return -1;
}
void work()
{
/* Code */
int sx,sy,ex,ey,lim;
cin>>lim;
while(cin>>sx>>sy>>ex>>ey) s.pb(mp(sx,sy),mp(ex,ey));
for(int i=1; i<=lim; i++)
if(~check(lim,i))
return (void)(cout<<(int)(check(lim,i)*4e6+i)<<'\n');
return;
}
\(\texttt{Day 16}\)
\(\texttt{Part 1}\)
观察数据,发现有贡献的点很少,其他的点全都是无用的。
我们设有贡献的点有 \(k\) 个,可以状压 dp,记录当前有哪些点已经被释放过了,当前在哪个点,以及当前时间即可。
转移分 \(3\) 类:定在原地,释放该点,移动到另一个点。
时间复杂度 \(O(2^kk^2t+n^3)\).
#include <bits/stdc++.h>
using namespace std;
#define fir(x) (get<0>(x))
#define sec(x) (get<1>(x))
#define pii pair<int,int>
#define pb emplace_back
const int mod=998244353;
const int maxn=(1<<16)+10;
map<string,int> id;
vector<pii> pts;
int f[maxn][16][31];
int d[60][60];
int n,tot;
int get(const string &s)
{
if(id.count(s)) return id[s];
return (id[s]=++tot);
}
void work()
{
/* Code */
cin>>n; string s; int m,val,k;
memset(d,0x3f,sizeof(d));
for(int i=1; i<=n; i++) d[i][i]=0;
while(cin>>m>>s>>val)
{
int now=get(s);
if(val||s=="AA") pts.pb(now,val);
for(int i=1; i<=m; i++) cin>>s,d[now][get(s)]=1;
}
n=tot,k=pts.size();
memset(f,-0x3f,sizeof(f));
for(int l=1; l<=n; l++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
d[i][j]=min(d[i][j],d[i][l]+d[l][j]);
for(int i=0; i<k; i++) if(get("AA")==fir(pts[i])) f[0][i][1]=0;
for(int t=1; t<30; t++)
for(int st=0; st<(1<<k); st++)
for(int i=0; i<k; i++)
{
f[st][i][t+1]=max(f[st][i][t+1],f[st][i][t]);
for(int j=0; j<k; j++)
{
int u=fir(pts[i]),v=fir(pts[j]);
if(t+d[u][v]<=30)
f[st][j][t+d[u][v]]=max(f[st][j][t+d[u][v]],f[st][i][t]);
}
if(!((st>>i)&1))
f[st^(1<<i)][i][t+1]=max(f[st^(1<<i)][i][t+1],f[st][i][t]+sec(pts[i])*(30-t));
}
int tar=0;
for(int st=0; st<(1<<k); st++)
for(int i=0; i<k; i++)
tar=max(tar,f[st][i][30]);
cout<<tar<<'\n';
return;
}
\(\texttt{Part 2}\)
\(\texttt{Day 17}\)
\(\texttt{Part 1}\)
\(\texttt{Part 2}\)
\(\texttt{Day 18}\)
\(\texttt{Part 1}\)
\(\texttt{Part 2}\)
\(\texttt{Day 19}\)
\(\texttt{Part 1}\)
\(\texttt{Part 2}\)
\(\texttt{Day 20}\)
\(\texttt{Part 1}\)
\(\texttt{Part 2}\)
\(\texttt{Day 21}\)
\(\texttt{Part 1}\)
\(\texttt{Part 2}\)
\(\texttt{Day 22}\)
\(\texttt{Part 1}\)
\(\texttt{Part 2}\)
\(\texttt{Day 23}\)
\(\texttt{Part 1}\)
\(\texttt{Part 2}\)
\(\texttt{Day 24}\)
\(\texttt{Part 1}\)
\(\texttt{Part 2}\)
\(\texttt{Day 25}\)
\(\texttt{Part 1}\)
\(\texttt{Part 2}\)

浙公网安备 33010602011771号