Advent Of Code 2024 Solution

\[\Large\texttt{Advent Of Code 2024} \]


\(\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\)
于是我们直接把那些特殊的图形找出来,然后就可以发现一个圣诞树。
据情况可能找到的是一个横着的或竖着的圣诞树。
唐氏乱搞题。放一下我的圣诞树。

img

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)
posted @ 2024-12-04 17:08  静谧幽蓝  阅读(283)  评论(0)    收藏  举报