As AnttiP has pointed out, this can be shorter with a change of approach and full rewrite. Let's look at some simpler manipulations of your original code though just for the sake of it though:
Here was my first attempt at eliminating the exec
hack:
85 bytes
lambda N:[b for i in range(1,N+1)if N*N%i==0for b in[A:=[N+i,N+N*N//i],A[::-1]]][:-1]
Attempt This Online!
Unfortunately, as you may notice, it doesn't work, because :=
is not allowed in for
comprehension iterable expression.
There's another place we can put it in though: the if
clause just before it:
91 bytes
lambda N:[b for i in range(1,N+1)if(A:=[N+i,N+N*N//i])and N*N%i==0for b in[A,A[::-1]]][:-1]
Attempt This Online!
This can be shortened a bit by combining the comparison ==0
:
89 bytes
lambda N:[b for i in range(1,N+1)if 0in(A:=[N+i,N+N*N//i],N*N%i)for b in[A,A[::-1]]][:-1]
Attempt This Online!
The [:-1]
at the end is just to remove the final duplicated result of (x, x)
, but we can remove this just by switching to a set comprehension (and using a tuple instead of a list, because it's hashable):
84 bytes
lambda N:{b for i in range(1,N+1)if 0in(A:=(N+i,N+N*N//i),N*N%i)for b in[A,A[::-1]]}
Attempt This Online!
The output is no longer in order, so hopefully that doesn't matter here.
I'm working on going further than this... stay tuned
f=lambda N:[(x,y)for x in range(1,N**3)for y in range(N**3)if(x+y)*N==x*y]
\$\endgroup\$