Advent Of Code 2024 Solution
\(\texttt{Intro}\)
这是一个从每年 12 月 1 日开始的为期 25 天的编程挑战,每天中午 1 pm 会公布一道题。
每道题会有两个部分,你需要用编程解决每一个部分。
本文会使用 C++
,Python
进行编程。
网址:https://adventofcode.com/2024
\(\texttt{Day 1}\)
\(\texttt{Part 1}\)
import re
a=list(map(lambda it:list(map(int,re.findall(r"\d+",it))),open(0).readlines()))
x,y=[_[0] for _ in a].sort(),[_[1] for _ in a].sort()
print(sum(abs(x[i]-y[i]) for i in range(len(x))))
\(\texttt{Part 2}\)
import re
a=list(map(lambda it:list(map(int,re.findall(r"\d+",it))),open(0).readlines()))
x,y=[_[0] for _ in a],[_[1] for _ in a]
print(sum(i*y.count(i) for i in x))
\(\texttt{Day 2}\)
\(\texttt{Part 1}\)
a=list(map(lambda it:list(map(int,it.split())),open(0).readlines()))
tar=0
for it in a:
if sorted(it)==it or sorted(it,reverse=True)==it :
fl=1
for i in range(1,len(it)):
if abs(it[i]-it[i-1])<1 or abs(it[i]-it[i-1])>3 :
fl=0
tar+=fl
print(tar)
\(\texttt{Part 2}\)
def check(it):
fl=True
if sorted(it)==it or sorted(it,reverse=True)==it :
for i in range(1,len(it)):
if abs(it[i]-it[i-1])<1 or abs(it[i]-it[i-1])>3 :
fl=False
else : fl=False
return fl
a=list(map(lambda it:list(map(int,it.split())),open(0).readlines()))
tar=0
for it in a:
fl=False
for i in range(len(it)):
fl|=check(it[:i]+it[i+1:])
tar+=int(fl)
print(tar)
\(\texttt{Day 3}\)
\(\texttt{Part 1}\)
import re
reg=r"mul\((\d+),(\d+)\)"
a=re.findall(reg,''.join(list(map(lambda it:it.strip(),open(0).readlines()))))
a=list(map(lambda it:re.match(reg,it),a))
a=list(map(lambda it:[int(it.group(1)),int(it.group(2))],a))
print(sum(i[0]*i[1] for i in a))
\(\texttt{Part 2}\)
import re
reg1=r"mul\(\d+,\d+\)|do\(\)|don't\(\)"
reg2=r"mul\((\d+),(\d+)\)|do\(\)|don't\(\)"
str=''.join(list(map(lambda it:it.strip(),open(0).readlines())))
a=re.findall(reg1,str)
enable,tar=True,0
for i in a:
if i=="do()": enable=True
elif i=="don't()": enable=False
elif enable:
it=re.match(reg2,i)
tar+=int(it.group(1))*int(it.group(2))
print(tar)
\(\texttt{Day 4}\)
\(\texttt{Part 1}\)
const string base="XMAS";
const int dx[9]={0,-1,-1,-1,0,0,1,1,1};
const int dy[9]={0,-1,0,1,-1,1,-1,0,1};
vector<string> a;
int n,m;
bool check(int x,int y) { return x>=0&&x<n&&y>=0&&y<m; }
void work()
{
/* Code */
string str; int tar=0;
while(cin>>str) a.pb(str),n++,m=str.size();
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(a[i][j]!='X') continue;
for(int k=1; k<=8; k++)
{
int xx=i+dx[k],yy=j+dy[k],fl=1;
for(int l=1; l<4; l++,xx+=dx[k],yy+=dy[k])
if(!check(xx,yy)||a[xx][yy]!=base[l])
fl=0;
tar+=fl;
}
}
cout<<tar<<'\n';
return;
}
\(\texttt{Part 2}\)
const string base="MAS";
const int dx[9]={0,-1,-1,1,1};
const int dy[9]={0,-1,1,-1,1};
vector<string> a;
int n,m;
bool check(int x,int y) { return x>=0&&x<n&&y>=0&&y<m; }
void work()
{
/* Code */
string str; int tar=0;
while(cin>>str) a.pb(str),n++,m=str.size();
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
// if(a[i][j]!='A') continue;
int sum=0;
for(int k=1; k<=4; k++)
{
int xx=i-dx[k],yy=j-dy[k],fl=1;
for(int l=0; l<3; l++,xx+=dx[k],yy+=dy[k])
if(!check(xx,yy)||a[xx][yy]!=base[l])
fl=0;
sum+=fl;
}
tar+=(sum>=2);
}
cout<<tar<<'\n';
return;
}
\(\texttt{Day 5}\)
\(\texttt{Part 1}\)
a,b=''.join(open(0).readlines()).split('\n\n')
a=list(map(lambda it:(int(it[0:2]),int(it[3:5])),a.split('\n')))
b=list(map(lambda it:list(map(int,it.split(','))),b.split('\n')))
tar=0
for it in b:
flag=True
for x,y in a:
if x in it and y in it:
if it.index(x)>it.index(y):
flag=False
if flag: tar+=it[len(it)//2]
print(tar)
\(\texttt{Part 2}\)
a,b=''.join(open(0).readlines()).split('\n\n')
a=list(map(lambda it:(int(it[0:2]),int(it[3:5])),a.split('\n')))
b=list(map(lambda it:list(map(int,it.split(','))),b.split('\n')))
tar=0
for it in b:
flag=True
for x,y in a:
if x in it and y in it:
if it.index(x)>it.index(y):
flag=False
if not flag:
temp,nxt=it,[]
while len(temp):
maxx,id=-1,0
for i in temp:
sum=0
for j in temp:
if (i,j) in a:
sum+=1
if maxx<sum: maxx,id=sum,i
nxt.append(id)
id=temp.index(id)
temp=temp[0:id]+temp[id+1:]
tar+=nxt[len(nxt)//2]
print(tar)
\(\texttt{Day 6}\)
\(\texttt{Part 1}\)
dx,dy=[-1,0,1,0],[0,1,0,-1]
a=[i.strip() for i in open(0).readlines()]
n,m=len(a),len(a[0])
sx,sy,dir=0,0,0
route=set()
for i in range(len(a)):
if a[i].count('^'):
sx,sy=i,a[i].index('^')
while sx>=0 and sx<n and sy>=0 and sy<m:
route.add((sx,sy))
xx,yy=sx+dx[dir],sy+dy[dir]
while xx>=0 and xx<n and yy>=0 and yy<m and a[xx][yy]=='#':
dir=(dir+1)%4
xx,yy=sx+dx[dir],sy+dy[dir]
sx,sy=xx,yy
print(len(route))
\(\texttt{Part 2}\)
dx,dy=[-1,0,1,0],[0,1,0,-1]
def work(sx,sy):
route,dir=set(),0
while sx>=0 and sx<n and sy>=0 and sy<m:
if (sx,sy,dir) in route:
return True
route.add((sx,sy,dir))
xx,yy=sx+dx[dir],sy+dy[dir]
while xx>=0 and xx<n and yy>=0 and yy<m and a[xx][yy]=='#':
dir=(dir+1)%4
xx,yy=sx+dx[dir],sy+dy[dir]
sx,sy=xx,yy
return False
a=[i.strip() for i in open(0).readlines()]
n,m=len(a),len(a[0])
sx,sy,tar=0,0,0
route=set()
print(n,m)
for i in range(len(a)):
if a[i].count('^'):
sx,sy=i,a[i].index('^')
for i in range(n):
for j in range(m):
if a[i][j]=='.':
a[i]=a[i][:j]+'#'+a[i][j+1:]
tar+=work(sx,sy)
a[i]=a[i][:j]+'.'+a[i][j+1:]
print(tar)
\(\texttt{Day 7}\)
\(\texttt{Part 1}\)
import re
a,tar=[[int(it) for it in re.findall(r'\d+',i)] for i in open(0).readlines()],0
for it in a:
v,t,fl=it[0],it[1:],False
for st in range(1<<(len(t)-1)):
s=t[0]
for i in range(len(t)-1):
if (st>>i)&1: s*=t[i+1]
else: s+=t[i+1]
if s==v: fl=True
tar+=v*fl
print(tar)
\(\texttt{Part 2}\)
import re
a,tar=[[int(it) for it in re.findall(r'\d+',i)] for i in open(0).readlines()],0
for it in a:
v,t,fl=it[0],it[1:],False
for st in range(3**(len(t)-1)):
s=t[0]
for i in range(len(t)-1):
if st%3==0: s*=t[i+1]
elif st%3==1: s+=t[i+1]
else: s=s*(10**len(str(t[i+1])))+t[i+1]
if s>v: break
st//=3
if s==v: fl=True
tar+=v*fl
print(tar)
\(\texttt{Day 8}\)
\(\texttt{Part 1}\)
a=[i.strip() for i in open(0).readlines()]
n,m=len(a),len(a[0])
p,s={},set()
for i in range(len(a)):
for j in range(len(a[i])):
if a[i][j]!='.':
if p.get(a[i][j])==None: p[a[i][j]]=[]
p[a[i][j]].append((i,j))
for it in p:
for i in p[it]:
for j in p[it]:
if i==j: continue
t=(2*i[0]-j[0],2*i[1]-j[1])
if t[0]>=n or t[0]<0 or t[1]>=m or t[1]<0: continue
s.add(t)
print(len(s))
\(\texttt{Part 2}\)
a=[i.strip() for i in open(0).readlines()]
n,m=len(a),len(a[0])
p,s={},set()
for i in range(len(a)):
for j in range(len(a[i])):
if a[i][j]!='.':
if p.get(a[i][j])==None: p[a[i][j]]=[]
p[a[i][j]].append((i,j))
for it in p:
for i in p[it]:
for j in p[it]:
if i==j: continue
t=i
while t[0]<n and t[0]>=0 and t[1]<m and t[1]>=0:
s.add(t)
t=(t[0]+i[0]-j[0],t[1]+i[1]-j[1])
print(len(s))
\(\texttt{Day 9}\)
\(\texttt{Part 1}\)
a=input()+'0'
s=[f',{i//2}'*int(a[i])+',-1'*int(a[i+1]) for i in range(0,len(a),2)]
s=''.join(s).split(',')[1:]
ed=len(s)
for i in range(0,len(s)):
while s[ed-1]=='-1': ed-=1
if i>=ed: break
if s[i]=='-1': s[i],s[ed-1]=s[ed-1],s[i]
print(sum(i*int(s[i]) for i in range(ed)))
\(\texttt{Part 2}\)
vector<pii> v;
string s;
void work()
{
/* Code */
cin>>s;
for(int i=0; i<s.size(); i++) v.pb((i&1? -1:i/2),s[i]-'0');
for(int i=(v.size()-1)/2; i; i--)
{
int pos=0;
for(int j=0; j<v.size(); j++) if(v[j].first==i) pos=j;
for(int j=0; j<pos; j++)
if(v[j].first==-1&&v[j].second>=v[pos].second)
{
v[j].second-=v[pos].second;
v[pos].first=-1;
v.insert(v.begin()+j,mp(i,v[pos].second));
break;
}
for(int j=v.size()-1; j; j--)
if(v[j].first==-1&&v[j-1].first==-1)
v[j-1].second+=v[j].second,v[j].second=0;
}
int pos=0,sum=0;
for(auto [it,len]:v)
{
if(it!=-1) for(int i=pos; i<pos+len; i++) sum+=it*i;
pos+=len;
}
cout<<sum<<'\n';
return;
}
\(\texttt{Day 10}\)
\(\texttt{Part 1}\)
dx,dy=[-1,1,0,0],[0,0,-1,1]
a=[i.strip() for i in open(0).readlines()]
n,m,s=len(a),len(a[0]),0
for i in range(n):
for j in range(m):
if a[i][j]=='0':
q,tar=[(i,j,0)],set()
while len(q):
now=q[0]; q.pop(0)
x,y,st=now
if st==9: tar.add((x,y))
for k in range(4):
xx,yy=x+dx[k],y+dy[k]
if xx>=0 and xx<n and yy>=0 and yy<m and int(a[xx][yy])==st+1:
q.append((xx,yy,st+1))
s+=len(tar)
print(s)
\(\texttt{Part 2}\)
dx,dy=[-1,1,0,0],[0,0,-1,1]
a=[i.strip() for i in open(0).readlines()]
n,m,s=len(a),len(a[0]),0
for i in range(n):
for j in range(m):
if a[i][j]=='0':
q,tar=[(i,j,0)],0
while len(q):
now=q[0]; q.pop(0)
x,y,st=now
if st==9: tar+=1
for k in range(4):
xx,yy=x+dx[k],y+dy[k]
if xx>=0 and xx<n and yy>=0 and yy<m and int(a[xx][yy])==st+1:
q.append((xx,yy,st+1))
s+=tar
print(s)
\(\texttt{Day 11}\)
\(\texttt{Part 1 & Part 2}\)
两个部分可以用一样的代码,只不过是将输入中的 \(m\) 改成 \(25\) 或 \(75\) 即可。
map<pii,int> vis;
int a[maxn];
int n,m;
int dfs(int dep,int now)
{
if(!dep) return 1;
if(now<100&&vis[mp(dep,now)]) return vis[mp(dep,now)];
if(!now) return dfs(dep-1,1);
string str=to_string(now);
int tar=0;
if(!(str.size()&1))
tar=dfs(dep-1,stoi(str.substr(0,str.size()/2)))
+dfs(dep-1,stoi(str.substr(str.size()/2,str.size()/2)));
else tar=dfs(dep-1,now*2024);
if(now<100) vis[mp(dep,now)]=tar;
return tar;
}
void work()
{
/* Code */
cin>>n>>m; int tar=0;
for(int i=1,x; i<=n; i++) cin>>x,tar+=dfs(m,x);
cout<<tar<<'\n';
return;
}
\(\texttt{Day 12}\)
\(\texttt{Part 1}\)
dx,dy=[-1,1,0,0],[0,0,-1,1]
def bfs(sx,sy):
global v
c,s,q=0,0,[(sx,sy)]
v[sx][sy]=1
while len(q):
x,y=q[0]
q.pop(0)
s+=1
for i in range(4):
xx,yy=x+dx[i],y+dy[i]
if xx>=0 and xx<n and yy>=0 and yy<m and a[xx][yy]==a[sx][sy]:
if not v[xx][yy]:
q.append((xx,yy))
v[xx][yy]=1
else: c+=1
return (c,s)
a=[i.strip() for i in open(0).readlines()]
v=[[0]*len(it) for it in a]
n,m,s=len(a),len(a[0]),0
for i in range(n):
for j in range(m):
if not v[i][j]:
t=bfs(i,j)
s+=t[0]*t[1]
print(s)
\(\texttt{Part 2}\)
dx,dy=[-1,1,0,0],[0,0,-1,1]
def bfs(sx,sy):
global v
c,s,q=0,0,[(sx,sy)]
ex=[[[] for _ in ' '*(n+1)] for _ in ' '*4]
ey=[[[] for _ in ' '*(m+1)] for _ in ' '*4]
v[sx][sy]=1
while len(q):
x,y=q[0]
q.pop(0)
s+=1
for i in range(4):
xx,yy=x+dx[i],y+dy[i]
if xx>=0 and xx<n and yy>=0 and yy<m and a[xx][yy]==a[sx][sy]:
if not v[xx][yy]:
q.append((xx,yy))
v[xx][yy]=1
else:
if x==xx: ey[i][min(y,yy)+1].append(x)
if y==yy: ex[i][min(x,xx)+1].append(y)
for j in range(4):
for i in range(n+1): ex[j][i].sort()
for i in range(m+1): ey[j][i].sort()
for j in range(4):
c+=sum(sum(i[it]+1!=i[it+1] for it in range(len(i)-1))+1 if len(i) else 0 for i in ex[j])
c+=sum(sum(i[it]+1!=i[it+1] for it in range(len(i)-1))+1 if len(i) else 0 for i in ey[j])
return (c,s)
a=[i.strip() for i in open(0).readlines()]
v=[[0]*len(it) for it in a]
n,m,s=len(a),len(a[0]),0
for i in range(n):
for j in range(m):
if not v[i][j]:
t=bfs(i,j)
s+=t[0]*t[1]
print(s)
\(\texttt{Day 13}\)
\(\texttt{Part 1}\)
from z3 import *
import re
a=[[int(i) for i in re.findall(r'\d+',it)] for it in open(0).readlines()]
tar=0
for i in range(0,len(a),4):
x,y=Ints('x y')
sol=Solver()
sol.add(a[i][0]*x+a[i+1][0]*y==a[i+2][0])
sol.add(a[i][1]*x+a[i+1][1]*y==a[i+2][1])
if sol.check()==sat:
m=sol.model()
tar+=m[x]*3+m[y]
print(simplify(tar))
\(\texttt{Part 2}\)
from z3 import *
import re
a=[[int(i) for i in re.findall(r'\d+',it)] for it in open(0).readlines()]
tar=0
for i in range(0,len(a),4):
x,y=Ints('x y')
sol=Solver()
sol.add(a[i][0]*x+a[i+1][0]*y==a[i+2][0]+10000000000000)
sol.add(a[i][1]*x+a[i+1][1]*y==a[i+2][1]+10000000000000)
if sol.check()==sat:
m=sol.model()
tar+=m[x]*3+m[y]
print(simplify(tar))
\(\texttt{Day 14}\)
\(\texttt{Part 1}\)
import re
def fit(x,l,r,n): return l<=x%n and x%n<=r
a=[[int(i) for i in re.findall(r'[-\d]+',it)] for it in open(0).readlines()]
n,m=a[0]; a.pop(0); tar=1
tar*=sum(fit(sx+dx*100,0,n//2-1,n) and fit(sy+dy*100,0,m//2-1,m) for sx,sy,dx,dy in a)
tar*=sum(fit(sx+dx*100,n//2+1,n,n) and fit(sy+dy*100,0,m//2-1,m) for sx,sy,dx,dy in a)
tar*=sum(fit(sx+dx*100,0,n//2-1,n) and fit(sy+dy*100,m//2+1,m,m) for sx,sy,dx,dy in a)
tar*=sum(fit(sx+dx*100,n//2+1,n,n) and fit(sy+dy*100,m//2+1,m,m) for sx,sy,dx,dy in a)
print(tar)
\(\texttt{Part 2}\)
这个 \(\texttt{Part 2}\) 是真的唐氏。他没有告诉你那个圣诞树长什么样,所以我们要猜。
首先将 \(1000\) 步以内的图找出来,通过大力观察法发现,有个别图形有一个矩形的区域。
我们发现,这些区域的出现是有周期的。是 \(101\) 和 \(103\)。
于是我们直接把那些特殊的图形找出来,然后就可以发现一个圣诞树。
据情况可能找到的是一个横着的或竖着的圣诞树。
唐氏乱搞题。放一下我的圣诞树。
import re
fout=open('temp.out','w')
a=[[int(i) for i in re.findall(r'[-\d]+',it)] for it in open('temp.in','r').readlines()]
n,m=a[0]; a.pop(0); tar=1
for i in range(22,100000,101):
b=[((sx+dx*i)%n,(sy+dy*i)%m) for sx,sy,dx,dy in a]
b.sort(key=lambda i:i[0])
v=[[' ']*n for _ in ' '*m]
for x,y in b: v[y][x]='#'
print(i,'\n'.join([''.join(i) for i in v]),file=fout)
\(\texttt{Day 15}\)
\(\texttt{Part 1}\)
def swap(x,y):
global a
xx,yy=a[x[0]][x[1]],a[y[0]][y[1]]
a[x[0]]=a[x[0]][:x[1]]+yy+a[x[0]][x[1]+1:]
a[y[0]]=a[y[0]][:y[1]]+xx+a[y[0]][y[1]+1:]
a=[i.strip() for i in open(0).readlines()]
a='\n'.join(a).split('\n\n')
s,a,pos=''.join(a[1].split('\n')),a[0].split('\n'),(0,0)
for i in range(len(a)):
if ~a[i].find('@'):
pos=(i,a[i].find('@'))
for i in s:
dir=[(-1,0),(1,0),(0,-1),(0,1)]['^v<>'.find(i)]
nxt=(pos[0]+dir[0],pos[1]+dir[1])
while a[nxt[0]][nxt[1]] not in '.#':
nxt=(nxt[0]+dir[0],nxt[1]+dir[1])
lst=(-dir[0],-dir[1])
if a[nxt[0]][nxt[1]]=="#": continue
while nxt!=pos:
temp=(nxt[0]+lst[0],nxt[1]+lst[1])
swap(nxt,temp)
nxt=temp
pos=(pos[0]+dir[0],pos[1]+dir[1])
print(sum(sum((i*100+j)*(a[i][j]=='O') for j in range(len(a[i]))) for i in range(len(a))))
\(\texttt{Part 2}\)
def push(id,dir):
global blk
blk[id][0]+=dir[0]
blk[id][1]+=dir[1]
for i in range(len(blk)):
if blk[i][2]: continue
if blk[i][0]==blk[id][0] and abs(blk[i][1]-blk[id][1])<=1:
blk[i][2]=1
push(i,dir)
return
a=''.join(open(0).readlines()).split('\n\n')
s,a,pos=''.join(a[1].split('\n')),a[0],(0,0)
blk,a=[],a.split('\n')
for i in range(len(a)):
for j in range(len(a[i])):
if a[i][j]=='O': blk.append([i,2*j,0])
a='\n'.join(a).replace('#','##').replace('.','..').replace('@','@.').replace('O','..').split('\n')
for i in range(len(a)):
if ~a[i].find('@'):
pos=[i,a[i].find('@')]
a[i]=a[i].replace('@','.')
for c in s:
dir=[(-1,0),(1,0),(0,-1),(0,1)]['^v<>'.find(c)]
nxt=[pos[0]+dir[0],pos[1]+dir[1]]
id=-1
for i in range(len(blk)):
if nxt[0]==blk[i][0] and 0<=nxt[1]-blk[i][1] and nxt[1]-blk[i][1]<=1:
blk[i][2],id=1,i
if not ~id:
if a[nxt[0]][nxt[1]]!='#': pos=nxt
continue
push(id,dir)
flag=True
for i in range(len(blk)):
if a[blk[i][0]][blk[i][1]]=='#' or a[blk[i][0]][blk[i][1]+1]=='#':
flag=False
if a[nxt[0]][nxt[1]]=='#': flag=False
for i in range(len(blk)):
if blk[i][2]==1 and not flag:
blk[i][0]-=dir[0]
blk[i][1]-=dir[1]
blk[i][2]=0
if flag: pos=nxt
print(sum(i[0]*100+i[1] for i in blk))
\(\texttt{Day 16}\)
\(\texttt{Part 1}\)
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
string a[maxn];
bool vis[maxn][maxn][4];
int f[maxn][maxn][4];
int n,m;
void work()
{
/* Code */
string str;
while(cin>>str) a[n++]=str,m=str.size();
memset(f,0x7f,sizeof(f));
queue<tup> q; q.push(mt(n-2,1,3));
f[n-2][1][3]=0; vis[n-2][1][3]=true;
while(q.size())
{
tup now=q.front(); q.pop();
int x=get<0>(now),y=get<1>(now),ty=get<2>(now);
vis[x][y][ty]=false;
for(int i=0; i<4; i++)
{
int xx=x+dx[i],yy=y+dy[i];
if(xx<0||xx>=n||yy<0||yy>=m||a[xx][yy]=='#') continue;
int val=f[x][y][ty]+1+1000*(i!=ty);
if(val<f[xx][yy][i])
{
f[xx][yy][i]=val;
if(!vis[xx][yy][i]) q.push(mt(xx,yy,i));
}
}
}
int tar=1e18; for(int i=0; i<4; i++) tar=min(tar,f[1][m-2][i]);
cout<<tar<<'\n';
return;
}
\(\texttt{Part 2}\)
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
string a[maxn];
bool vis[maxn][maxn][4];
bool ava[maxn][maxn];
int f[maxn][maxn][4];
int g[maxn][maxn][4];
int n,m;
void work()
{
/* Code */
string str;
while(cin>>str) a[n++]=str,m=str.size();
memset(f,0x3f,sizeof(f));
memset(g,0x3f,sizeof(g));
queue<tup> q; q.push(mt(n-2,1,3));
f[n-2][1][3]=0; vis[n-2][1][3]=true;
while(q.size())
{
tup now=q.front(); q.pop();
int x=get<0>(now),y=get<1>(now),ty=get<2>(now);
vis[x][y][ty]=false;
for(int i=0; i<4; i++)
{
int xx=x+dx[i],yy=y+dy[i];
if(xx<0||xx>=n||yy<0||yy>=m||a[xx][yy]=='#') continue;
int val=f[x][y][ty]+1+1000*(i!=ty);
if(val<f[xx][yy][i])
{
f[xx][yy][i]=val;
if(!vis[xx][yy][i]) q.push(mt(xx,yy,i)),vis[xx][yy][i]=true;
}
}
}
for(int i=0; i<4; i++) q.push(mt(1,m-2,i)),g[1][m-2][i]=0,vis[1][m-2][i]=true;
while(q.size())
{
tup now=q.front(); q.pop();
int x=get<0>(now),y=get<1>(now),ty=get<2>(now);
vis[x][y][ty]=false;
for(int i=0; i<4; i++)
{
int xx=x+dx[i],yy=y+dy[i];
if(xx<0||xx>=n||yy<0||yy>=m||a[xx][yy]=='#') continue;
int val=g[x][y][ty]+1+1000*(i!=ty);
if(val<g[xx][yy][i])
{
g[xx][yy][i]=val;
if(!vis[xx][yy][i]) q.push(mt(xx,yy,i)),vis[xx][yy][i]=true;
}
}
}
int res=1e18; for(int i=0; i<4; i++) res=min(res,f[1][m-2][i]);
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
for(int l=0; l<4; l++)
if(a[i][j]!='#')
for(int k=0; k<4; k++)
{
int temp=(k<2? 1-k:5-k);
int val=1000*(l!=temp);
if(f[i][j][l]+g[i][j][k]+val==res) ava[i][j]=true;
}
int tar=0; for(int i=0; i<n; i++) for(int j=0; j<m; j++) tar+=ava[i][j];
cout<<tar<<'\n';
return;
}
\(\texttt{Day 17}\)
\(\texttt{Part 1}\)
import re
a=[[int(i) for i in re.findall(r'\d+',it)] for it in open(0).readlines()]
x,y,z,s,i=a[0][0],a[1][0],a[2][0],a[-1],0
out=[]
while i<len(s):
ty,num,flag=s[i],s[i+1],True
if ty not in [1,3,4]: num=(num if num<4 else [x,y,z][num-4])
if ty==0: x>>=num
elif ty==1: y^=num
elif ty==2: y=num&7
elif ty==3: i,flag=(i if x==0 else num),(x==0)
elif ty==4: y^=z
elif ty==5: out.append(num&7)
elif ty==6: y=x>>num
elif ty==7: z=x>>num
if flag: i+=2
print(','.join(map(str,out)))
\(\texttt{Part 2}\)
这次的 \(\texttt{Part 2}\) 就有点意思了。
这需要你自己将这个程序写出来分析。
像我的是 Program: 2,4,1,5,7,5,1,6,0,3,4,3,5,5,3,0
就写成:
do
b=a&7
b^=5
c=a>>b
b^=6
a>>=3
b^=c
output b&7
while a!=0
简化得到
do
b1=(a&7)^5
b2=b1^6^(a>>b1)
a>>=3
output b2&7
while a
于是把 \(a\) 每 \(3\) 位分一组,直接暴搜 \(b_1\),检查 \(b_2\) 是否为答案就可以得到解了。
tx,ty=5,6
def dfs(dep,a):
global s,tar
if dep<0:
tar=min(tar,a)
return
for b1 in range(3,8):
b2=b1^ty^(a>>(b1-3))
if b2&7==s[dep]: dfs(dep-1,(a<<3)+(b1^tx))
for b1 in range(0,3):
ta=(a<<3)+(b1^tx)
b2=b1^ty^(ta>>b1)
if b2&7==s[dep]: dfs(dep-1,(a<<3)+(b1^tx))
return
import re
a=[[int(i) for i in re.findall(r'\d+',it)] for it in open(0).readlines()]
s,tar=a[-1],1e20
dfs(len(s)-1,0)
print(tar)
\(\texttt{Day 18}\)
\(\texttt{Part 1}\)
dx,dy=[-1,1,0,0],[0,0,-1,1]
a=[i.strip() for i in open(0).readlines()]
s,n,m=map(int,a[0].split())
a=[list(map(int,i.split(','))) for i in a[1:]][:s]
vis=[[False]*(m+1) for _ in range(n+1)]
f=[[1e18]*(m+1) for _ in range(n+1)]
mp=[[0]*(m+1) for _ in range(n+1)]
for x,y in a:
if x<=n and y<=m: mp[y][x]=1
q,f[0][0],vis[0][0]=[[0,0]],0,True
while len(q):
now=q[0]; q.pop(0)
vis[now[0]][now[1]]=False
for i in range(4):
x,y=now[0]+dx[i],now[1]+dy[i]
if x<0 or x>n or y<0 or y>m or mp[x][y]: continue
if f[x][y]>f[now[0]][now[1]]+1:
f[x][y]=f[now[0]][now[1]]+1
if not vis[x][y]:
q.append([x,y])
vis[x][y]=True
print(f[n][m])
\(\texttt{Part 2}\)
def get(x,y):
global n
return x*(n+1)+y
def find(x):
if x==fa[x]: return x
fa[x]=find(fa[x])
return fa[x]
def merge(x,y):
x,y=find(x),find(y)
if x==y: return False
fa[x],siz[y]=y,siz[y]+siz[x]
return True
def addpt(x,y):
for i in range(4):
xx,yy=x+dx[i],y+dy[i]
if xx<0 or xx>n or yy<0 or yy>m or mp[xx][yy]: continue
merge(get(x,y),get(xx,yy))
return find(get(0,0))==find(get(n,m))
dx,dy=[-1,1,0,0],[0,0,-1,1]
a=[i.strip() for i in open(0).readlines()]
n,m=map(int,a[0].split())
a=[list(map(int,i.split(','))) for i in a[1:]]
siz,fa=[1]*((n+1)*(m+1)),[i for i in range((n+1)*(m+1))]
mp=[[0]*(m+1) for _ in range(n+1)]
tot=(n+1)*(m+1)
for x,y in a:
if x<=n and y<=m:
mp[y][x]=1
tot-=1
for i in range(n+1):
for j in range(m+1):
if not mp[i][j]: addpt(i,j)
flag=True
for x,y in a[::-1]:
mp[y][x]=0
tot+=1
if addpt(y,x) and flag:
print(str(x)+','+str(y))
flag=False
\(\texttt{Day 19}\)
\(\texttt{Part 1}\)
a=[i.strip() for i in open(0).readlines()]
s,a,tar=a[0].split(', '),a[2:],0
for t in a:
t=' '+t
f=[0]*len(t)
f[0]=1
for i in range(1,len(t)):
for p in s:
if i<len(p): continue
if p!=t[i-len(p)+1:i+1]: continue
f[i]+=f[i-len(p)]
tar+=(f[len(t)-1]>0)
print(tar)
\(\texttt{Part 2}\)
a=[i.strip() for i in open(0).readlines()]
s,a,tar=a[0].split(', '),a[2:],0
for t in a:
t=' '+t
f=[0]*len(t)
f[0]=1
for i in range(1,len(t)):
for p in s:
if i<len(p): continue
if p!=t[i-len(p)+1:i+1]: continue
f[i]+=f[i-len(p)]
tar+=f[len(t)-1]
print(tar)
\(\texttt{Day 20}\)
\(\texttt{Part 1}\)
dx,dy=[-1,1,0,0],[0,0,-1,1]
a=[i.strip() for i in open(0).readlines()]
n,m,st=len(a)-1,len(a[0]),int(a[-1]); a.pop()
vis=[[False]*m for _ in range(n)]
f=[[1e18]*m for _ in range(n)]
ss,tt=(0,0),(0,0)
for i in range(len(a)):
if a[i].find('S')!=-1: ss=(i,a[i].find('S'))
if a[i].find('E')!=-1: tt=(i,a[i].find('E'))
q,f[ss[0]][ss[1]],vis[ss[0]][ss[1]]=[[ss[0],ss[1]]],0,True
while len(q):
now=q[0]; q.pop(0)
vis[now[0]][now[1]]=False
for i in range(4):
x,y=now[0]+dx[i],now[1]+dy[i]
if x<0 or x>n or y<0 or y>m or a[x][y]=='#': continue
if f[x][y]>f[now[0]][now[1]]+1:
f[x][y]=f[now[0]][now[1]]+1
if not vis[x][y]:
q.append([x,y])
vis[x][y]=True
tar=0
for i in range(1,n-1):
for j in range(1,m-1):
if a[i][j]!='#':
for k in range(4):
x,y=i+2*dx[k],j+2*dy[k]
if x<0 or x>=n or y<0 or y>=m: continue
if a[x][y]!='#':
tar+=(f[x][y]-f[i][j]-2>=st)
print(tar)
\(\texttt{Part 2}\)
dx,dy=[-1,1,0,0],[0,0,-1,1]
a=[i.strip() for i in open(0).readlines()]
n,m=len(a)-1,len(a[0])
st,sk=map(int,a[-1].split())
a.pop()
vis=[[False]*m for _ in range(n)]
f=[[1e18]*m for _ in range(n)]
ss,tt=(0,0),(0,0)
for i in range(len(a)):
if a[i].find('S')!=-1: ss=(i,a[i].find('S'))
if a[i].find('E')!=-1: tt=(i,a[i].find('E'))
q,f[ss[0]][ss[1]],vis[ss[0]][ss[1]]=[[ss[0],ss[1]]],0,True
while len(q):
now=q[0]; q.pop(0)
vis[now[0]][now[1]]=False
for i in range(4):
x,y=now[0]+dx[i],now[1]+dy[i]
if x<0 or x>n or y<0 or y>m or a[x][y]=='#': continue
if f[x][y]>f[now[0]][now[1]]+1:
f[x][y]=f[now[0]][now[1]]+1
if not vis[x][y]:
q.append([x,y])
vis[x][y]=True
tar=0
for i in range(0,n):
for j in range(0,m):
if a[i][j]!='#':
for k in range(i-sk,i+sk+1):
if k<0 or k>=n: continue
left=sk-abs(k-i)
for l in range(j-left,j+left+1):
if l<0 or l>=m: continue
if a[k][l]!='#':
dis=abs(k-i)+abs(l-j)
tar+=(f[k][l]-f[i][j]-dis>=st)
print(tar)
\(\texttt{Day 21}\)
\(\texttt{Part 1}\)
def get(ty,x): return npos["0123456789A-".index(x)] if not ty else dpos['^v<>A-'.index(x)]
npos=[(3,1),(2,0),(2,1),(2,2),(1,0),(1,1),(1,2),(0,0),(0,1),(0,2),(3,2),(3,0)] # 0123456789A-
dpos=[(0,1),(1,1),(1,0),(1,2),(0,2),(0,0)] # ^v<>A-
a=[i.strip() for i in open(0).readlines()]
def dfs(fl,s):
if fl==3: return len(s)
if not len(s): return 0
lst,tar='A',0
for i in s:
l,n,b=get(fl,lst),get(fl,i),get(fl,'-')
res=1e18
col='v'*max(n[0]-l[0],0)+'^'*max(l[0]-n[0],0)
row='>'*max(n[1]-l[1],0)+'<'*max(l[1]-n[1],0)
if l[0]!=b[0] or n[1]!=b[1]: res=min(res,dfs(fl+1,row+col+'A'))
if n[0]!=b[0] or l[1]!=b[1]: res=min(res,dfs(fl+1,col+row+'A'))
tar+=res; lst=i
return tar
print(sum(int(i[:-1])*dfs(0,i) for i in a))
\(\texttt{Part 2}\)
def get(ty,x): return npos["0123456789A-".index(x)] if not ty else dpos['^v<>A-'.index(x)]
npos=[(3,1),(2,0),(2,1),(2,2),(1,0),(1,1),(1,2),(0,0),(0,1),(0,2),(3,2),(3,0)] # 0123456789A-
dpos=[(0,1),(1,1),(1,0),(1,2),(0,2),(0,0)] # ^v<>A-
a=[i.strip() for i in open(0).readlines()]
vis=[{} for i in ' '*26]
def dfs(fl,s):
if fl==26: return len(s)
if not len(s): return 0
if s in vis[fl]: return vis[fl][s]
lst,tar='A',0
for i in s:
l,n,b=get(fl,lst),get(fl,i),get(fl,'-')
res=1e18
col,row='v'*(n[0]-l[0])+'^'*(l[0]-n[0]),'>'*(n[1]-l[1])+'<'*(l[1]-n[1])
if l[0]!=b[0] or n[1]!=b[1]: res=min(res,dfs(fl+1,row+col+'A'))
if n[0]!=b[0] or l[1]!=b[1]: res=min(res,dfs(fl+1,col+row+'A'))
tar+=res; lst=i
vis[fl][s]=tar
return tar
print(sum(int(i[:-1])*dfs(0,i) for i in a))
\(\texttt{Day 22}\)
\(\texttt{Part 1}\)
a,mod=[int(i) for i in open(0).readlines()],16777216
for _ in ' '*2000:
a=[i^(i<<6)%mod for i in a]
a=[i^(i>>5)%mod for i in a]
a=[i^(i<<11)%mod for i in a]
print(sum(a))
\(\texttt{Part 2}\)
a,mod=[int(i) for i in open(0).readlines()],16777216
tar={}
for i in a:
t,d,l,res=[],[],i,{}
for _ in ' '*2000:
n=l^(l<<6)%mod
n=n^(n>>5)%mod
n=n^(n<<11)%mod
t.append(n%10)
d.append(n%10-l%10)
l=n
for j in range(3,len(t)):
k=str(d[j-3:j+1])
if k not in res: res[k]=t[j]
for j in res:
if j in tar: tar[j]+=res[j]
else: tar[j]=res[j]
print(max(tar[i] for i in tar))
\(\texttt{Day 23}\)
\(\texttt{Part 1}\)
a,s,r=[i.strip().split('-') for i in open(0).readlines()],{},set()
for i,j in a: s[i],s[j]=[],[]
for i,j in a:
s[i].append(j)
s[j].append(i)
for i in s:
if not i.find('t'):
for j in s[i]:
for k in s[i]:
if j!=k and i!=j and i!=k and k in s[j]:
t=[i,j,k]; t.sort()
r.add(str(t))
print(len(r))
\(\texttt{Part 2}\)
def check(arr,pos):
for i in arr:
if pos not in s[i]: return False
return True
def dfs(arr:list,pos:int):
global r
if len(r)<len(arr): r=[i for i in arr]
if pos>=len(p): return
dfs(arr,pos+1)
if check(arr,p[pos]):
arr.append(p[pos])
dfs(arr,pos+1)
arr.pop()
a,s,r=[i.strip().split('-') for i in open(0).readlines()],{},[]
for i,j in a: s[i],s[j]=[],[]
for i,j in a:
s[i].append(j)
s[j].append(i)
p=[i for i in s]
dfs([],0)
r.sort()
print(','.join(r))
\(\texttt{Day 24}\)
\(\texttt{Part 1}\)
def add(p:str):
global s
if p not in r: return
for op,q,t in r[p]:
if t in s or q not in s: continue
v=(s[p]&s[q] if op=="AND" else s[p]|s[q] if op=="OR" else s[p]^s[q])
s[t]=v; add(t)
a,b=''.join(open(0).readlines()).split('\n\n')
a,b=[i.split(': ') for i in a.split('\n')],[i.split() for i in b.split('\n')]
s,r={},{}
for i,j,k,x,l in b:
if i not in r: r[i]=[]
if k not in r: r[k]=[]
r[i].append((j,k,l))
r[k].append((j,i,l))
for i,j in a:
s[i]=int(j)
add(i)
t=[]
for i in s:
if i[0]=='z': t.append((int(i[1:]),s[i]))
print(sum(j<<i for i,j in t))
\(\texttt{Part 2}\)
什么人工模拟题。
注意到他模拟的是加法,于是语句构成的就是一个 全加器。
把流程图输出后,每一个部分形如这样:
...
stk OR fhg -> mkg // From previous part
...
x02 AND y02 -> mrq
x02 XOR y02 -> sbv
mkg AND sbv -> wwd
mrq OR wwd -> gfq
mkg XOR sbv -> z02
于是可以直接上正则表达式判断。
/(\S+) AND (\S+) -> (\S+)
\1 XOR \2 -> (\S+)
(\S+) AND \4 -> (\S+)
\3 OR \6 -> (\S+)
(\S+) XOR \4 -> z(\d+)/gm
判断完后会有 \(4\) 个部分不符合匹配规则,手动改正即可。
顺便安利一个正则表达式测试网站:https://regex101.com/
def add(p:str):
global s,v
s.add(p)
if p not in r: return
for op,q,t in r[p]:
if t in s or q not in s: continue
if q[0]=='x' and p[0]=='y':
if q not in v:
v.add(p); v.add(q)
print()
print(q,op,p,'->',t)
add(t)
a,b=''.join(open(0).readlines()).split('\n\n')
a,b=[i.split(': ') for i in a.split('\n')],[i.split() for i in b.split('\n')]
r,s,v={},set(),set()
for i,j,k,x,l in b:
if i not in r: r[i]=[]
if k not in r: r[k]=[]
r[i].append((j,k,l))
r[k].append((j,i,l))
for i in r: r[i].sort(key=lambda i:['AND','XOR','OR'].index(i[0]))
for i,j in a: add(i)
\(\texttt{Day 25}\)
\(\texttt{Part 1}\)
a=''.join(open(0).readlines()).split('\n\n')
a,s,t,r=[i.split('\n') for i in a],[],[],0
for i in a:
if i[0]=="#####": s.append([sum(i[k][j]=='#' for k in range(7)) for j in range(5)])
if i[0]!="#####": t.append([sum(i[k][j]=='#' for k in range(7)) for j in range(5)])
for i in s:
for j in t:
f=True
for k in range(5): f&=(i[k]+j[k]<=7)
r+=f
print(r)