Advent Of Code 2022 Solution

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


\(\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}\)

posted @ 2024-12-05 18:23  静谧幽蓝  阅读(59)  评论(0)    收藏  举报