#AoC 2022 | Code Golf Solutions & Spoilers
4240 messages Β· Page 5 of 5 (latest)
uh no
the inner board I mean
probably nothing we can do with that
Hey guys am I able to ask for a feedback on here ?
it depends
Basically a developer sent me a demo and wants a feedback on it
then that's your job, isn't it?
Am I wrong to ask for more feedback ?
how did you manage to find yourself in the golf thread for aoc looking for help on that
lmao
really depends on what kind of agreement you have with the dev
Idk I use discord maybe once every year so I donβt know how it works Iβll go find the right place
i wasn't bothered so i just did my solution as a golf
[Day 25] 339
import math as m
x=sum(sum((D:={'=':-2,'-':-1,'0':0,'1':1,'2':2,-2:'=',-1:'-',0:'0',1:'1',2:'2'})[v]*5**i for i,v in enumerate(n[::-1]))for n in open(0).read().split('\n'));y=[x//(5**b)%5for b in range(m.floor(m.log(x,5))+1)]
for i in range(len(y)-1):j=y[i];y[i+1]+=2<j<6;y[i]={3:-2,4:-1,5:0}.get(j,j)
print(''.join(D[v] for v in y[::-1]))
probably a better solution out there tho
mine kinda big
Today's is great for golfing
[Day 25] 164
D="=-012"
s=''
c=0
N=open(0).read().split()
for i in range(99):
for n in N: c+=D.index(n.zfill(99)[-i-1])-2
d=(c+2)%5-2;s=D[d+2]+s;c=(c-d)//5
print(s.lstrip('0'))
ok yeah that's definitely better lmao
Just don't bother with base 10 π
the heck is zfill
Pad left with 0s
N=open(0).read().split()
Can this not be*N,=open(0)
from enira
[Day 25] 163
D="=-012"
s=''
N=open(c:=0).read().split()
for i in range(99):
for n in N: c+=D.index(n.zfill(99)[-i-1])-2
d=(c+2)%5-2;s=D[d+2]+s;c=(c-d)//5
print(s.lstrip('0'))
Yep, and works with strings too
Here's my original solution which I based on - much easier to understand algorithm π
https://github.com/piotr-piatkowski/aoc/blob/main/2022/d25#L14
[Day 25] 161
D="=-012"
s=''
N=open(c:=0).read().split()
for i in range(99):
for n in N: c+=D.index(n.zfill(99)[~i])-2
d=(c+2)%5-2;s=D[d+2]+s;c=(c-d)//5
print(s.lstrip('0'))
ok why is there a space there
[Day 25] 160
D="=-012"
s=''
N=open(c:=0).read().split()
for i in range(99):
for n in N:c+=D.index(n.zfill(99)[~i])-2
d=(c+2)%5-2;s=D[d+2]+s;c=(c-d)//5
print(s.lstrip('0'))
Oh yeah, I was just to fix this (I forgot about that trick with ~i)
from enira
[Day 25] 158
D="=-012"
s=''
N=open(c:=0).read().split()
for i in range(99):
for n in N:c+=D.index(n.zfill(99)[~i])-2
d=(c+2)%5;s=D[d]+s;c=(c-d+2)//5
print(s.lstrip('0'))
[Day 25] 157
D="=-012"
s=''
N=open(c:=0).read().split()
for i in range(99):
for n in N:c+=D.index(n.zfill(99)[~i])-2
s=D[d:=(c+2)%5]+s;c=(c-d+2)//5
print(s.lstrip('0'))
[Day 25] 155
D="=-012"
s=''
N=open(c:=0).read().split()
for i in range(99):
for n in N:c+=D.index(n.zfill(99)[~i])-2
c+=2;s=D[c%5]+s;c=(c-c%5)//5
print(s.lstrip('0'))
[Day 25] 148
D="=-012"
s=''
N=open(c:=0).read().split()
for i in range(99):
for n in N:c+=D.index(n.zfill(99)[~i])-2
c+=2;s=D[c%5]+s;c//=5
print(s.lstrip('0'))
147, remove l from lstrip
no it removes the zeroes on the right as well
Oh worked for me. Lol mb
from enira
[Day 25] 143
D="=-012"
s=''
*N,=open(c:=0)
for i in range(99):
for n in N:c+=D.index(n.strip().zfill(99)[~i])-2
c+=2;s=D[c%5]+s;c//=5
print(s.lstrip('0'))
who/what is enira?
She/he got muted for being elitist 
partial from enira
[Day 25] 140
D="=-012"
s=''
*N,=open(c:=0)
for i in range(99):c+=sum(D.find(n.strip().zfill(99)[~i])-2for n in N)+2;s=D[c%5]+s;c//=5
print(s.lstrip('0'))
Does walrus for c reduce length?
Or is the loop execable?
you need the i from the loop
i personally don't find their average insults insulting but i'm probably just used to it

[Day 25] anyways 138 ```py
D="=-012"
s=''
*N,=open(c:=0)
for i in range(99):c=c//5+sum(D.find(n.strip().zfill(99)[~i])-2for n in N)+2;s=D[c%5]+s
print(s.lstrip('0'))
sad ```py
sum(['', 'a'],'')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sum() can't sum strings [use ''.join(seq) instead]
if you have a way to turn s into a sequence
you can always just do print(*s,sep='')
there's still the .lstrip('0') though
[Day 25] dangerous assumption that everyone has a 20-character output, 132 ```py
D="=-012"
*N,=open(c:=0)
print(''.join(D[(c:=c//5+sum(D.find(n.strip().zfill(99)[~i])-2for n in N)+2)%5]for i in range(99))[19::-1])
@urban torrent pls test
β«that includes the 0 at the -20th index
actually probably -21st
[Day 25] 130
D="=-012"
*N,=open(c:=0)
print(''.join(D[(c:=c//5+sum(D.find(n.strip().zfill(99)[~i])-2for n in N)+2)%5]for i in range(20))[::-1])
does this work then
yes
i also changed .zfill(99) to .zfill(20)
still the same thing
yep
equivalent but with 2 lines
[Day 25] 130
*N,D=*open(c:=0),"=-012"
print(''.join(D[(c:=c//5+sum(D.find(n.strip().zfill(20)[~i])-2for n in N)+2)%5]for i in range(20))[::-1])
how many numbers did you all get?
10 for everyone so won't matter
also I just realized this was probably a genuine question
oops
it's @orchid charm
You mean, the number of lines, i assume?
My discord on laptop seems to have died. Can't open it since the past hour
Is discord getting DDosed? : π
discord browser is working
Half the shit on my mobile isn't working either
not just syntax highlighting?
there doesn't seem to be any issue being reported by others
Idk wtf happened. I turned my phone off and on again and it works. Ffs
Literally nothing was loading except text
it does that sometimes
finally GOT my discord working! This works
nice
yeah, i have time today, I will update it. Do we have the solutions pinned or would I need to find them individually?
so the 130 also works?
nope
you're just gonna have to search for [Day x]
good luck π
we don't have moderators lurking around in this channel to pin solutions
yeah, works
π
π
actually probably easier to just go to the earliest none saved version and scroll down
also someone please do a better day 19 and day 22
I don't want my 1k+ golf to be the best day 22 golf
from functools import reduce
from itertools import count
from re import findall
from sys import stdin
# Part 1
# (S:=[*stdin.readlines()]) and (m:={i+1j*j:(c=='.') for i,s in enumerate(S[:-2]) for j,c in enumerate(s.rstrip()) if c in '.#'}) and (j:=lambda x,d:x+d if x+d in m else next(x-i*d for i in count() if x-i*d not in m)+d) and (x:=reduce(lambda x,p:(x[0],x[1]*1j*(1-2*(p=='R'))) if p in 'RL' else (reduce(lambda y,_:j(y,x[1]) if m[j(y,x[1])] else y,range(int(p)),x[0]),x[1]),findall('\d+|R|L',S[-1]),(min(m,key=lambda x:(x.real,x.imag)),1j))) and print(1000*x[0].real+4*x[0].imag+1004+[1j,1,-1j,-1].index(x[1]))
# Part 2
(S:=[*stdin.readlines()]) and (m:={i+1j*j:(c=='.') for i,s in enumerate(S[:-2]) for j,c in enumerate(s.rstrip()) if c in '.#'}) and (g:={}) or (n:=lambda x,d:[(x,-d*1j),(x-d*1j,d),(x+d*(1-1j),d*1j)][c(x,d)]) and (c:=lambda x,d:len({x-d*1j,x-d*1j+d}&m.keys())) and (f:=lambda x:(y:=c(*x)==2 and n(*x) or (z:=f(n(*x))) and (z[0]+c(*x) and z[1] or f(z[1])[1])) and g.update({x:(y[0],-y[1]),y:(x[0],-x[1])}) or (c(*y),n(*y))) and f(next((x,d) for x in m for d in [1,-1,1j,-1j] if x+d not in m and x+d*(1+1j) in m)) and (j:=lambda x,d:g.get((x,d),(x+d,d))) and (x:=reduce(lambda x,p:(x[0],x[1]*1j*(1-2*(p=='R'))) if p in 'RL' else reduce(lambda y,_:j(*y) if m[j(*y)[0]] else y,range(int(p)),x),findall('\d+|R|L',S[-1]),(min(m,key=lambda x:(x.real,x.imag)),1j))) and print(1000*x[0].real+4*x[0].imag+1004+[1j,1,-1j,-1].index(x[1]))
perhaps, this helps?
why are they 1k+
does this prove that day 22 was the hardest
because I'm bad at golfing
if I could figure out where the cube folding code is
maybe
actually probably
considering that's pretty short
I'd basically just scrap my entire thing tho
if only we could toggle trailing newlines
we'd be able to replace .strip() with [:-1]
[Day 25] 129
*N,D=*open(c:=0),"=-012"
print(''.join(D[(c:=c//5+sum(D.find(('0'*20+n.strip())[~i])-2for n in N)+2)%5]for i in range(20))[::-1])
have u tested it?
pretty sure that doesn't work
we need the string to be length 20
not just 20 zeroes
Works for me
replace '0'*20 with '0'*i
should work
from enira
[Day 25] 127
*N,D=*open(c:=0),"=-012"*99
print(''.join(D[c:=c//5+sum(D.find(('0'*i+n.strip())[~i])-2for n in N)+2]for i in range(20))[::-1])```
[Day 25] 126 bytes (works for me)
*N,D=*open(c:=0),"=-012"*9
print(''.join(D[c:=c//5+sum(D.find(('0'*i+n.strip())[~i])-2for n in N)+2]for i in range(20))[::-1])
Ah okay gotcha
also stop golfing and go finish aoc lmao
don't want you to get spoiled by some of the golfs
huh? i'm already done with everything lol wdym
I never keep any question unfinished for >24h
where do you. get the role?
do &aoc link in the bot commands channel
do you know who made this?
I spent like 4 hours on the plane deciphering it and it's pretty cool
don't wanna use it without giving proper credit
am back
go golf day 19
ok
[Day 19] 534
import re,math
I=lambda *x:1+max(*map(math.ceil,x),0)
q=n=0
Z=0,0
e=1
for _,A,B,C,D,E,F in(map(int,re.findall('\d+',l))for l in open(0).read().split('\n')):
def d(r,l,s,g,b,c,o,t):
global m;m=max(m,g)
if~-t*t/2+g>m and t>1:[d(r+o*v-w,l+c*v-x,s+b*v-y,g+z*(t-v),b+h,c+j,o+k,t-v)for v,w,x,y,z,h,j,k in((o<max(A,B,C,E)and I((A-r)/o),A,*Z*2,0,1),(D>c and I((B-r)/o),B,*Z*2,1,0),(c*(F>b)and I((C-r)/o,(D-l)/c),C,D,*Z,1,*Z),(b and I((E-r)/o,(F-s)/b),E,0,F,1,*Z,0))if v]
m=0;d(*Z*3,1,24);q+=_*m
if n<3:n+=1;d(*Z*3,1,32);e*=m
print(q,e)```
oh
my starting golf kinda sucks
k
this kept bothering me in my sleep last night so
[Day 19] 528
import re
I=lambda *x:1+max(*(-(-i//1)for i in x),0)
q=n=0
Z=0,0
e=1
for _,A,B,C,D,E,F in(map(int,re.findall('\d+',l))for l in open(0).read().split('\n')):
def d(r,l,s,g,b,c,o,t):global m;m=max(m,g);(~-t*t/2+g>m)*(t>1)and[d(r+o*v-w,l+c*v-x,s+b*v-y,g+z*(t-v),b+h,c+j,o+k,t-v)for v,w,x,y,z,h,j,k in((o<max(A,B,C,E)and I((A-r)/o),A,*Z*2,0,1),(D>c and I((B-r)/o),B,*Z*2,1,0),(c*(F>b)and I((C-r)/o,(D-l)/c),C,D,*Z,1,*Z),(b and I((E-r)/o,(F-s)/b),E,0,F,1,*Z,0))if v]
m=0;d(*Z*3,1,24);q+=_*m
if n<3:n+=1;d(*Z*3,1,32);e*=m
print(q,e)
[Day 22] 670
import re,functools as f
E,R=enumerate,f.reduce
J=1j
*b,_,s=open(0)
m={x+J*y:v>'('for x,r in E(b)for y,v in E(r)if v in'.#'}
p={}
g=lambda x,d:([(x,d/J),(x+d/J,d),(x+d-d*J,d*J)][l:=(x+d/J in m)+(x+d-d*J in m)],l)
def w(x):
global p;y,l=g(*x)
if l<2:z,k=w(y);y=z if l+k else w(z)[0]
p|={x:(y[0],-y[1]),y:(x[0],-x[1])};return g(*y)
w((50+99j,J))
for j in lambda x,d:([next(z for i in range(999)if(z:=x-i*d)not in m)+d,x+d][x+d in m],d),lambda x,d:p.get((x,d),(x+d,d)):x=R(lambda x,d:(x[0],x[1]*J*' L'.find(d))if d>'E'else R(lambda y,_:[y,j(*y)][m[j(*y)[0]]],[0]*int(d),x),re.findall('\d+|R|L',s),(50j,J));a,c=x;print(int(1000*a.real+4*a.imag+1004+[J,1,-J,-1].index(c)))
^base code
[Day 22] 669
import re,functools as f
E,R=enumerate,f.reduce
J=1j
*b,_,s=open(0)
m={x+J*y:v>'('for x,r in E(b)for y,v in E(r)if v in'.#'}
p={}
g=lambda x,d:([(x,d/J),(x+d/J,d),(x+d-d*J,d*J)][l:=(x+d/J in m)+(x+d-d*J in m)],l)
def w(x):
global p;y,l=g(*x)
if l<2:z,k=w(y);y=z if l+k else w(z)[0]
p|={x:(y[0],-y[1]),y:(x[0],-x[1])};return g(*y)
w((50+99j,J))
for j in lambda x,d:([next(z for i in(1,2,3)if(z:=x-50*i*d)not in m)+d,x+d][x+d in m],d),lambda x,d:p.get((x,d),(x+d,d)):x=R(lambda x,d:(x[0],x[1]*J*' L'.find(d))if d>'E'else R(lambda y,_:[y,j(*y)][m[j(*y)[0]]],[0]*int(d),x),re.findall('\d+|R|L',s),(50j,J));a,c=x;print(int(1000*a.real+4*a.imag+1004+[J,1,-J,-1].index(c)))
feels bad to be the only one left here

just me or does that generate the nets dynamically??
yes
it does
*raw_board, _, instructions = S
board: dict[complex, bool] = {x + y * 1j: v == '.' for x, row in enumerate(raw_board) for y, v in enumerate(row) if v in '.#'}
portals: dict[pos_facing, pos_facing] = {}
def right_left_hammer(pos: complex, facing: complex) -> 0|1|2:
global board
return (pos + facing * (-1j) in board) + (pos + facing * (1-1j) in board)
def movement(pos: complex, facing: complex) -> pos_facing:
match right_left_hammer(pos, facing):
case 0:
return pos, facing * (-1j)
case 1:
return pos + facing * (-1j), facing
case 2:
return pos + facing * (1-1j), facing * 1j
def fill_portal(pos: complex, facing: complex) -> tuple[0|1|2, pos_facing]:
global portals
rl_hammer = right_left_hammer(pos, facing)
y = movement(pos, facing)
if rl_hammer != 2:
z = fill_portal(*y)
if z[0] + rl_hammer:
y = z[1]
else:
y = fill_portal(*z[1])[1]
portals.update({
(pos, facing): (y[0], -y[1]),
y: (pos, -facing)
})
return right_left_hammer(*y), movement(*y)
fill_portal((50+99j), 1j)
print(portals)
current = 50j, 1j
for move in findall(r'\d+|R|L', instructions):
match move:
case 'L':
current = current[0], current[1] * 1j
case 'R':
current = current[0], current[1] * -1j
case step:
for _ in range(int(step)):
# possible to turn this into reduce and maybe reduce character count?
new_pos = portals.get(current, (current[0] + current[1], current[1]))
current = new_pos if board[new_pos[0]] else current
print(int(sum(prod(i) for i in zip((1000, 4, 1), (current[0].real+1, current[0].imag+1, {1j:0,1:1,-1j:2,-1:3}[current[1]])))))
here's my attempt to expand out the one-liner
50+99j is ```py
next((x,d) for x in m for d in [1,-1,1j,-1j] if x+d not in m and x+d*(1+1j) in m)
from what i can tell it traces out the boundary of the net and somehow pairs each edge up with its corresponding edge through recursion somehow
i have no idea
[Day 13] 307```py
e=enumerate
s=sorted([sum(x:=[[map(f:=lambda n,i=():list==type(n)and n and sum([f(v,(i,k))for k,v in e(n)],[])or[sum((x10**i for i,x in e(i)),[n,len(i)-5][n==[]])],map(eval,p))]forp,_ in zip([iter([*open(0),0])]3)],[]),[2],[6]])
i=s.index
print(sum(i+1for i,(v,p)in e(x)if v<p),(i([2])+1)(i([6])+1))
bitwise +1 saves chars in the print
also why not just directly assign the index function to s
[Day 13] 302 who needs +1 in print```py
e=enumerate
s=sorted([sum(x:=[[map(f:=lambda n,i=():list==type(n)and n and sum([f(v,(i,k))for k,v in e(n)],[])or[sum((x10**i for i,x in e(i)),[n,len(i)-5][n==[]])],map(eval,p))]forp,_ in zip([iter([*open(0),0])]*3)],[]),[2],[6],[]])
s=s.index
print(sum(i+1for i,(v,p)in e(x)if v<p),s([2])*s([6]))
[Day 13] 298 ```py
e=enumerate
s=sorted([sum(x:=[[map(f:=lambda n,i=():list==type(n)and n and sum([f(v,(i,k))for k,v in e(n)],[])or[sum((x10**i for i,x in e(i)),[n,len(i)-5][n==[]])],map(eval,p))]forp,_ in zip([iter([*open(0),0])]*3)],[]),[2],[6],[]]).index
print(sum(i+1for i,(v,p)in e(x)if v<p),s([2])*s([6]))
https://github.com/kaathewise/aoc2022
Here, she has one liners to mostly all questions for this year
wtf :/
why did he auto delete?
Oohh, okay
@sharp scarab This is one of the best things I started this month. You might like it as well π
nice
cool
did you use like a really old golf by accident
current best is 294 lmao
^
k
yeah i knew that golf looked weird
when i could easily just shave off like 10 chars
[Day 13] 284 ```py
e=enumerate
d=sorted(sum(x:=[[map(f:=lambda n,i=():int!=type(n)and sum((f(v,(i,k))for k,v in e(n)),[])or[sum((x<<i9for i,x in e(i)),[n,len(i)-5][n==[]])],map(eval,p))]forp,_ in zip(*[iter([open(0),0])]3)],[[2],[6]])).index
print(sum(-~i(v<p)for i,(v,p)in e(x)),~d([2])~d([6]))
nice
[Day 13] 282
e=enumerate
q=sum
d=sorted(q(x:=[[*map(f:=lambda n,i=():int!=type(n)and q((f(v,(*i,k))for k,v in e(n)),[])or[q((x<<i*9for i,x in e(i)),[n,len(i)-5][n==[]])],map(eval,p))]for*p,_ in zip(*[iter([*open(0),0])]*3)],[[2],[6]])).index
print(q(-~i*(v<p)for i,(v,p)in e(x)),~d([2])*~d([6]))```
[Day 13] 280 ```py
e=enumerate
q=sum
d=sorted(q(x:=[[map(f:=lambda n,i=():int!=type(n)and q((f(v,(i,k))for k,v in e(n)),[])or[q(x<<i9for i,x in e(i))+[n,len(i)-5][n==[]]],map(eval,p))]forp,_ in zip(*[iter([open(0),0])]3)],[[2],[6]])).index
print(q(-~i(v<p)for i,(v,p)in e(x)),~d([2])~d([6]))
[Day 13] 278
e=enumerate
q=sum
d=sorted(q(x:=[[*map(f:=lambda n,i=():str(n)>"9"and q((f(v,(*i,k))for k,v in e(n)),[])or[q(x<<i*9for i,x in e(i))+[n,len(i)-5][n==[]]],map(eval,p))]for*p,_ in zip(*[iter([*open(0),0])]*3)],[[2],[6]])).index
print(q(-~i*(v<p)for i,(v,p)in e(x)),~d([2])*~d([6]))```
that's smart
ty
[Day 13] 276
e=enumerate
q=sum
d=sorted(q(x:=[[*map(f:=lambda n,i=():str(n)>"9"and q((f(v,(*i,k))for k,v in e(n)),[])or[q(x<<i*9for i,x in e(i))+[n,len(i)-5][n==[]]],map(eval,p))]for*p,_ in zip(*[iter([*'26 ',*open(0),0])]*3)],[])).index
print(q(i*(v<p)for i,(v,p)in e(x)),~d([2])*~d([6]))
tbh i have no clue why that works
but it does
oh it's because nested enum always returns a list even if you just feed it a number
[Day 13] also 276
e=enumerate
q=sum
d=sorted(q(x:=[[*map(f:=lambda n,i=():str(n)>"9"and q((f(v,(*i,k))for k,v in e(n)),[])or[q(x<<i*9for i,x in e(i))+[n,len(i)-5][n==[]]],map(eval,p))]for _,*p in zip(*[iter([*' 26 ',*open(0)])]*3)],[])).index
print(q(i*(v<p)for i,(v,p)in e(x)),~d([2])*~d([6]))
i wouldn't have posted it but i was literally about to drift off to sleep when this suddenly came to me and i was like "ooh this should save a character" so i woke up just to do the golf and then i realize that you add 1c for the space before _,*p and so it doesn't save any characters
very sad
[Day 22] 668
import re,functools as f
E,R=enumerate,f.reduce
J=1j
*b,_,s=open(0)
m={x+J*y:v>'('for x,r in E(b)for y,v in E(r)if v in'.#'}
p={}
g=lambda x,d:([(x,d/J),(x+d/J,d),(x+d-d*J,d*J)][l:=(x+d/J in m)+(x+d-d*J in m)],l)
def w(x):
global p;y,l=g(*x)
if l<2:z,k=w(y);y=z if l+k else w(z)[0]
p|={x:(y[0],-y[1]),y:(x[0],-x[1])};return g(*y)
w((50+99j,J))
for j in lambda x,d:([next(z for i in(1,2,3)if(z:=x-50*i*d)not in m)+d,x+d][x+d in m],d),lambda x,d:p.get((x,d),(x+d,d)):x=R(lambda x,d:(x[0],x[1]*J*' L'.find(d))if d>'E'else R(lambda y,_:[y,j(*y)][m[j(*y)[0]]],[0]*int(d),x),re.findall('\d+|\w',s),(50j,J));a,c=x;print(int(1000*a.real+4*a.imag+1004+[J,1,-J,-1].index(c)))
x-~x//~2 should work then
no bitwise floats
oh it's a float whoops
we made the same mistake dw
-x%5*x//4 should give the same amount of characters
it's one character longer but it's next to an and
go ahead
[Day 9] 229
*f,=map(str.split,open(0))
for n in 2,10:t=[0];k=t*n;[exec("k[0]+=1j**'RDL'.find(m);x=1\nwhile x<n:d=k[x-1]-k[x];a,b=d.real,d.imag;k[x]+=abs(d)>=2and-a%5*a//4+1j*(-b%5*b//4);x+=1\nt+=k[-1],;"*int(v))for m,v in f];print(len({*t}))
slight modification so i can actually see part 1 without it being buried by a wall of syntax warnings
*f,=map(str.split,open(0))
for n in 2,10:t=[0];k=t*n;[exec("k[0]+=1j**'RDL'.find(m);x=1\nwhile x<n:d=k[x-1]-k[x];a,b=d.real,d.imag;k[x]+=2<=abs(d)and-a%5*a//4+1j*(-b%5*b//4);x+=1\nt+=k[-1],;"*int(v))for m,v in f];print(len({*t}))
still 229