デイヴ Profile picture
5 Dec, 48 tweets, 22 min read
For this year's #AdventOfCode, my goal is to get each day's solution in the most readable format that will fit in a tweet. Striving for a compromise between conciseness and (subjective) elegance… 🧵
#AdventOfCode Day 1 (in Python 🐍):
# (relies on a few input assumptions)

data = [int(i) for i in open('01')]

print("Part 1:",
next(x*y for x in data for y in data if x+y == 2020))

print("Part 2:",
next(x*y*z for x in data for y in data for z in data if x+y+z == 2020))
#AdventOfCode Day 2 in 🐍

import re
L = [re.split('[: \-]', l) for l in open('02')]
L = [(int(p1), int(p2), [c == ch for c in pwd])
   for p1, p2, ch, _, pwd in L]

print("Part 1:",
sum(n1<= sum(m)<= n2 for n1, n2, m in L),
"Part 2:",
sum(m[p1-1]^m[p2-1] for p1, p2, m in L))
#AdventOfCode Day 3 in 🐍:

import math
G = [l.strip() for l in open('03')]
res = [sum(G[v][r*i % len(g[0])] == '#' for i,v in enumerate(range(0, len(G), d)))
 for r, d in ([1,1], [3,1], [5,1], [7,1], [1,2])]

print(f"Part 1:", res[1], "\nPart 2:", math.prod(res)) Image
#AdventOfCode 4
import re
D = open('04').read().split('\n\n')

print('Pt 1:', sum(not(set(['byr','eyr','iyr','hgt','ecl','hcl','pid'])
- set(f[:3] for f in re.split('\s', d))) for d in D))

rng = {'b':(1920,2003), 'i':(2010,2021), 'e':(2020,2031),
'hcm':(150,194), 'hin':(59,77)}
print('Pt 2:',sum(sum([
*[int(d) in range(*rng.get(c[0]+u,[0])) for c,d,u in re.findall(r'([ebi]yr|hgt):(\d+)(in|cm)?\b',l)],
*[bool(re.search(p+r'\b',l)) for p in [
 'ecl:(amb|blu|brn|gry|grn|hzl|oth)',
 'hcl:#[\da-f]{6}',
 'pid:\d{9}']],
]) == 7
for l in D)) Image
#AdventOfCode Day 5 in #Python. Nice and clean:

ids = [sum(2**i * (1 if b in 'BR' else 0) for i,b in enumerate(reversed(s.strip())))
for s in open('05')]

print("Part 1:", max(ids),
"\nPart 2:", next(s+1 for s in ids if s+1 not in ids and s+2 in ids)) Image
#AdventOfCode2020 Day 6 in #Python

from collections import Counter
data = [
(Counter(l.replace('\n', '')), len(l.split('\n')))
for l in open('06').read().split('\n\n')
]

print('Pt 1:',
sum(len(g) for g,_ in data),

'\nPt 2:',
sum(v == t for g,t in data for v in g.values())) Image
#AdventOfCode Day 7 in #Python (2 tweets)

from collections import Counter
𝘽 = {
c1+c2: Counter({
k1+k2: int(n) for n, k1, k2 in zip(r[::4], r[1::4], r[2::4]) if n != 'no'
})
for c1, c2, _, _, *r in [l.split() for l in open('07')]
}
# 1/2
# 2/2 Day 7
ℱ = {}
def bags_in(b, n=1):
if b not in ℱ:
ℱ[b] = sum([bags_in(*x) for x in 𝘽[b].items()], 𝘽[b])
return Counter({c: ℱ[b][c]*n for c in ℱ[b]})

print('Pt1', sum('shinygold' in bags_in(b) for b in 𝘽),
'\nPt2', sum(bags_in('shinygold').values())) Image
#AoC Day 8

import networkx as nx
𝓟 = [(l[0], int(l[4:])) for l in open('08')]

G = nx.DiGraph((n,n+(a if c == 'j' else 1), {'a': (a if c == 'a' else 0)}) for n,(c,a) in enumerate(𝓟))
cy = nx.find_cycle(G, 0)

print('Pt 1:', nx.shortest_path_length(G, 0, cy[-1][0], 'a'))
# 1/2
nx.set_node_attributes(G, {n:{'i':a} for n,a in enumerate(𝓟)})
T= len(𝓟)
for s,t in cy:
 c,a= G.nodes[s]['i']
 u= s + {'j':1,'n':a,'a':0}[c]
 if nx.has_path(G,u,T):
  G.remove_edge(s,t)
  G.add_edge(s,u, a=0)
  break
print('Pt 2:', nx.shortest_path_length(G,0,T,'a')) Image
#AoC 8 pure 🐍
𝓟 = [(l[:3],int(l[4:])) for l in open('08')]
def run(P):
 𝒜,IP,℮ = 0,0,set()
 while IP<len(P) and IP not in ℮:
  ℮.add(IP)
  𝒾,a = P[IP]
  if 𝒾=='jmp': IP+= a-1
  if 𝒾=='acc': 𝒜+= a
  IP+= 1
 return(IP >= len(P), 𝒜)
print('Pt 1', run(𝓟)[1])
for l,(𝒾,a) in enumerate(𝓟):
if 𝒾 == 'jmp':
𝒾 = 'nop'
elif 𝒾 == 'nop':
𝒾 = 'jmp'
b, acc = run(𝓟[:l] + [(𝒾,a)] + 𝓟[(l+1):])
if b:
print('Part 2:', acc)
break Image
#AoC D 9
N=[int(n) for n in open('09')]
p=25
ok=lambda n,S: any(1 for j in range(p) if n-S[j] in S[j+1:])

x=next(n for i,n in enumerate(N[p:]) if not ok(n,sorted(N[i:i+p])))

C=[]
for n in N:
 C+=[n]
 while sum(C)>x: C.pop(0)
 if len(C)>1 and sum(C)==x: print(x,min(C)+max(C)) Image
#AdventOfCode 10
A= [int(i) for i in open('10')]
J= [0,*sorted(A),max(A)+3]
δ= [i-j for i,j in zip(J[1:],J)]
Δ=[1+p for p,d in enumerate(δ) if d==3]
𝓣=[1,1,2,4,7]
L=[𝓣[j-i-1] for i,j in zip([0]+Δ,Δ)]
import math
print('1:',len(Δ)*(len(δ)-len(Δ)),'2:',math.prod(L)) Image
#AdventOfCode Day 11 in 🐍 (2 tweets)

D = [l.strip() for l in open('11')]
P = { (x,y): 1
for x, Y in enumerate(D)
for y, s in enumerate(Y) if s == 'L'}

Δ=[-1,0,1]

# 1/2
def s(P,𝝆,𝝉):
 N=lambda x,y:sum(next((P[x+r*h,y+r*v] for r in range(1,𝝆+1) if (x+r*h,y+r*v) in P),0) for h in Δ for v in Δ)
 while 1:
  Q={p:N(*p)<𝝉+2 if P[p] else N(*p)==0 for p in P}
  if P==Q: return sum(P.values())
  P=Q
print('Pt1:',s(P,1,3),'Pt2:',s(P,len(D),4)) Image
#AdventOfCode Day 12 in 🐍

# Move:
ℳ = lambda x,y,dx,dy,d: (x+d*dx, y+d*dy)

# Rotate:
cos, sin = [1,0,-1,0], [0,1,0,-1]
ℛ = lambda x,y,t: (x*cos[t]-y*sin[t], x*sin[t]+y*cos[t])

A = {'L': 90, 'R': -90}
𝓦 = { 1:[1,0], 2:[10,1] } # initial waypoints for part 1&2

# 1/2
for p,W in 𝓦.items():
 P= [0,0]
 for i in open('12'):
  c,n= i[0],int(i[1:])
  if c=='F': P=ℳ(*P,*W,n)
  elif c in A: W=ℛ(*W, n//A[c]%4)
  else:
   r= ℛ(1,0,'ENWS'.index(c))
   if p-1: W=ℳ(*W,*r,n)
   else: P=ℳ(*P,*r,n)
 print('Pt',p,abs(P[0])+abs(P[1])) Image
#AdventOfCode Day 13
t,B = open('13')
B = [(i,int(b)) for i,b in enumerate(B.split(',')) if b!='x']

x,y = min(((b-int(t)) % b, b) for _,b in B)
print('Pt 1:', x*y)

N,t = 1,0
for dt,b in B:
t = next(t for t in range(t,int(1e64),N) if (t+dt)%b==0)
N *= b
print('Pt 2:', t) Image
#AoC 14.1
import collections as c
L= [(0,b.strip()) if a[1]=='a' else (int(a[4:-2]),int(b)) for a,b in [l.split('=') for l in open('14')]]
ℜ= lambda m,x:int(m.replace('X',x),2)
M= c.defaultdict(int)
for a,b in L:
 if a:M[a]= (b|ℜ(m,'0')) & ℜ(m,'1')
 else: m=b
sum(M.values())
#Aoc 14.2
def A(m):
 if not m: yield ''; return
 for n in A(m[1:]):
  for x in {'0':['X'], '1':['1'], 'X':['0','1']}[m[0]]: yield x+n
M= c.defaultdict(int)
for a,b in L:
 if a:
  for n in A(m): M[(a | ℜ(n,'0')) & ℜ(n,'1')]= b
 else: m=b
print('Pt2:', sum(M.values())) Image
#AdventOfCode 15 🐍
D = [int(n) for n in open('15').read().split(',')]

for pt,stop in ([1,2020],[2,30000000]):
 S = {n:t for t,n in enumerate(D[:-1])}
 x = D[-1]
 for i in range(len(D), stop):
  nx = i-1-S[x] if x in S else 0
  S[x] = i-1
  x = nx
 print(f'Pt {pt}:',x) Image
#AoC 16.1
import re
D= list(open('16'))
T= [int(i) for l in [D[22]]+D[25:] for i in l.split(',')]

R= [set([*range(int(a),int(b)+1), *range(int(c),int(d)+1)])
for _,a,b,c,d in [re.split(':|-|or ', r) for r in D[:20]]]

U= set.union(*R)
print('1:',sum(n for n in T if n not in U))
#16.2
M, *VT = [T[i:i+20] for i in range(0,len(T),20) if set(T[i:i+20]) <= U]

p = 1
for _ in range(20):
 for i in range(20):
  F = [all(t[i] in r for t in VT) for r in R]
  if sum(F) == 1:
   n = F.index(1)
   R[n] = {}
   if n < 6: p *= M[i]

print('Part 2:', p) Image
#AoC 17
G = lambda d: {(x,y, * [0]*(d-2))
   for y,X in enumerate(open('17').read().split('\n'))
   for x,c in enumerate(X) if c == '#'}

from itertools import product as pd

𝑅 = lambda X: range(min(X)-1, max(X)+2)
# 1/2
# 2/2

def GoL(d):
 𝑁 = lambda i: sum(tuple(a+b for a,b in zip(i,δ)) in P for δ in pd(*[[-1,0,1]]*d))
 P = G(d)

 for c in range(6):
  P = {i for i in pd(*(𝑅([x[n] for x in P]) for n in range(d)))
    if (i in P and 2<𝑁(i)<5) or 𝑁(i)==3}
 print(len(P))

GoL(3)
GoL(4) Image
#AoC Day 18
import ast as a
NT= a.NodeTransformer
cl= a.copy_location

class T1(NT):
 def visit_Sub(_,n): return cl(a.Mult(),n)
𝓔 = lambda s,T,D: eval(compile(T().visit(a.parse(s.translate(D),'','eval')),'','eval'))

print('Pt1:',sum(𝓔(l,T1,{42:'-'}) for l in open('18')))
#1/2
#2/2 #AdventOfCode Day 18 in 🐍

class T2(NT):
def visit_Add(_,n): return cl(a.Mult(),n)
def visit_Mult(_,n): return cl(a.Add(),n)

print('Pt2:', sum(𝓔(l, T2, {43:'*', 42:'+'}) for l in open('18')))
# 43 and 42 are ASCII for '+' and '*' respectively Image
#AoC 19
R,T= [t.split('\n') for t in open('19').read().split('\n\n')]
D= {k:v for k,v in [r.split(': ') for r in R]}
def B(r):
 if r in D: return B(D[r])
 if '"' in r: return r[1]
 j,s= ('|',' | ') if '|' in r else ('',' ')
 return f"({j.join(B(i) for i in r.split(s))})"
#1/2
#AdventOfCode Day 19 #2/2

import re
print('Part 1:', sum(bool(re.match(B('0')+'$', s)) for s in T))

P = "(" + '|'.join(f"{B('42')}{{{i+1},}}{B('31')}{{{i},{i}}}" for i in range(1,9)) + ")$"
# (I'm not proud…)

print('Part 2:', sum(1 for s in T if re.match(P,s))) Image
#AdventOfCode Day 20 will not fit in 2 tweets (not without some unspeakably ugly hacks)…

Instead, a reasonably elegant version that fits in less than 30 lines…

(GitHub version here: github.com/zedrdave/adven…) Image
#AdventOfCode Day 20

Oh, what the hell, here is a finely-crafted 4-tweet solution!
It's still surprisingly readable 😃

(check the screenshot for a commented version) Image
𝒏= '\n'
𝕛,𝕁= ''.join, 𝒏.join
from itertools import accumulate as 𝒞
P= {int(p[5:9]):p[11:] for p in open('20').read().split(2*𝒏)}

def 𝑻(p):
 X = {*𝒞(4*[p], lambda x,_: 𝕁(𝕛(l[::-1]) for l in zip(*x.split(𝒏))))}
 return X | {𝕁(l[::-1] for l in x.split(𝒏)) for x in X}
𝑬= lambda p,i: [p[:10],p[9::11],p[-10:],p[0::11]][i]
Z= {z for p in P for z in 𝑻(P[p])}
𝙈= lambda p,d: next((z for z in Z-𝑻(p) if 𝑬(z,(d+2)%4)==𝑬(p,d)), 0)

K = [k for k in P if sum(not 𝙈(P[k], i) for i in range(4)) == 2]
import math
print('Pt1',math.prod(K))
p= next(p for p in 𝑻(P[K[0]]) if (𝙈(p,2) and 𝙈(p,3)))
𝑳= lambda p,d: [*𝒞([p]+[d]*11, 𝙈)]

d=12
G = 𝕁( 𝕛(b[i:i+8] for b in B[::-1])
 for B in [𝑳(a,3) for a in 𝑳(p,2)]
 for i in range(d,90,d-1))

import regex as re
w= '[.#\n]{77}'
𝛹= f'#.{w+"#....#"*3}##{w}.#{"..#"*5}'
#AdventOfCode Day 20 in 🐍 4/4
for H in 𝑻(G):
m = len(re.findall(𝛹,H,0,0,-1,1)) # overlapped = True
if m: print('Part 2:', sum(c == '#' for l in G for c in l) - 15*m)
#AoC 21
F= [({*i.split()},{*a.split(', ')})
for i,a in [l.strip()[:-1].split(' (contains ') for l in open('21')]]
𝐔= set.union
A= 𝐔(*[a for _,a in F])
P= {aa: set.intersection(*[i for i,a in F if aa in a]) for aa in A}
print('Part 1:',sum(len(i-𝐔(*P.values())) for i,_ in F)) Image
#AdventOfCode Day 21 in #Python #2/2
C = {}
while len(C) < len(P):
a,i = next((k,v) for k,v in P.items() if len(v) == 1)
C[a] = [*i][0]
P = {k:(v-i) for k,v in P.items()}

print('Part 2:', ','.join(v for k,v in sorted(C.items())))
#AdventOfCode Day 22 in 🐍
def 𝓟(p, q, P1=0):
 S={0}
 while p and q:
  h = {(*p,0,*q)}
  if h&S: return [1]
  S |= h
  c,d = p.pop(0),q.pop(0)
  w = c>d if P1 or c>len(p) or d>len(q) else 𝓟(p[:c],q[:d])[0]
  if w: p+=(c,d)
  else: q+=(d,c)
 return (p,q)

# 1/2 Image
#AdventOfCode Day 22 in #Python
# 2/2

for part in (1,2):
p,q = [[int(i) for i in p[10:].split('\n')]
for p in open('22/input.txt').read().split('\n\n')]

p,q = 𝓟(p,q, part==1)

print(f'Part {part}:', sum((i+1)*c for i,c in enumerate((p+q)[::-1])))
#AoC Day 23

def play(C, n):
 L= {k:v for k,v in zip(C, C[1:]+C[:1])}
 L[0]= 0
 c= C[0]
 for _ in range(n):
  x= L[c]
  y= L[x]
  z= L[y]
  L[c]= L[z]
  d= c-1
  while d in (x,y,z,0): d = d-1 if d else len(C)
  L[z]= L[d]
  L[d]= x
  c= L[c]
 return L

#1/2 Image
#adventofcode2020 Day 23 #2/2

C = [int(i) for i in open('23').read()]
L = play(C, 100)
c,s = L[1],''
while c != 1:
s += str(c)
c = L[c]
print('Part 1:', s)

n = 1000000
C += range(max(C)+1, n+1)
L = play(C, 10*n)
print('Part 2:', L[1]*L[L[1]])
#AoC 24
D= {'w':(-1,0),'nw':(0,-1),'ne':(1,-1),'e':(1,0),'se':(0,1),'sw':(-1,1)}
𝓜= lambda x,y,a,b: (x+a,y+b)

𝐓=set()
for l in open('24'):
 P=(0,0)
 while l.strip():
  n= 2 if l[:2] in D else 1
  P= 𝓜(*P,*D[l[:n]])
  l= l[n:]
 𝐓 ^= {P}

print("Part 1:",len(𝐓))
#1/2 Image
#AdventOfCode 24
#2/2
𝓝= lambda *p: sum(𝓜(*p,*D[k]) in 𝐓 for k in D)
𝓑= lambda n: range(min(x[n] for x in 𝐓)-1, max(x[n] for x in 𝐓)+2)
for d in range(100):
 𝐓= {(x,y) for x in 𝓑(0) for y in 𝓑(1) if ((x,y) in 𝐓 and 𝓝(x,y)==1) or 𝓝(x,y)==2}
print("Part 2:", len(𝐓))
#AoC 24: Animated!

for d in range(100):
 𝐓= {(x,y) for x in 𝓑(0) for y in 𝓑(1) if ((x,y) in 𝐓 and 𝓝(x,y)==1) or 𝓝(x,y)==2}
 w=38
 print('\033\143'+'\n'.join((' '*(y%2)+''.join('⬛️' if (x-w,y-w) in 𝐓 else '⬜️' for x in range(2*w))) for y in range(2*w)))
 time.sleep(.1)
#AdventOfCode 25

p1,p2 = [int(l) for l in open('25')]
def 𝓔(n, pk=0, l=-1):
 i,c = 0,1
 while True:
  c = (c*n) % 20201227
  if c == pk: return i
  elif i == l: return c
  i += 1
l1,l2 = 𝓔(7,p1),𝓔(7,p2)
assert 𝓔(p1,l=l2) == 𝓔(p1,l=l1)

print('🎄🎁⭐️', 𝓔(p1, l=l2))

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with デイヴ

デイヴ Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!