I have a coding problem that goes like this:

Given a positive integer \$N\$, return a list of all possible pairs of positive integers \$(x,y)\$ such that $$\frac1x+\frac1y=\frac1N$$

I already solved the problem using Python, but I was wondering how I can code golf it. The following is my attempt at golfing (I try to follow some tips on the tips page):

108 bytes

exec("f=lambda N:[b for i in range(1,N+1)if N*N%i==0"+"for b in[%s,%s[::-1]]][:-1]"%(("[N+i,N+N*N//i]",)*2))

Try it online!

Ungolfed code for better readability

def f(N):
 for i in range(1,N+1):
  if N*N%i==0:
 return l[:-1]

Try it online!

  • \$\begingroup\$ Out of curiosity, is this a planned code-golf challenge? Not that I'm gonna plan a solution in advance, but it seems like a real nice challenge. \$\endgroup\$
    – ophact
    Jan 29, 2022 at 17:27
  • \$\begingroup\$ @ThisFieldIsRequired No, I was just wondering how I can golf my own code for this problem. \$\endgroup\$
    – Aiden Chow
    Jan 29, 2022 at 17:28
  • \$\begingroup\$ @AnttiP That works too... I guess I immediately approached the problem mathematically without thinking of brute force solutions. \$\endgroup\$
    – Aiden Chow
    Jan 29, 2022 at 17:50
  • \$\begingroup\$ Small correction: 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\$
    – AnttiP
    Jan 29, 2022 at 17:59

2 Answers 2


Python 3.8 (pre-release), 60 bytes

f=lambda N:[[N+i,N+N*N//i]for i in range(1,N*N+1)if 1>N*N%i]

Try it online!

No need for reversing:

We just generate every fraction for which the first denominator is a divisor of N squared.

  • \$\begingroup\$ Oh yeah, I guess I got tunnel vision with the reversing thing. Also the if 1>N*N%i is pretty smart too. \$\endgroup\$
    – Aiden Chow
    Jan 29, 2022 at 17:57
  • \$\begingroup\$ // can be / in Python 2 for -1 byte \$\endgroup\$
    – pxeger
    Jan 29, 2022 at 17:59
  • \$\begingroup\$ @pxeger Yep! but I don't do python 2. \$\endgroup\$
    – ophact
    Jan 29, 2022 at 18:00
  • \$\begingroup\$ That just output 30.0 instead of 30 but maybe still reasonable? \$\endgroup\$
    – l4m2
    Jan 29, 2022 at 18:07
  • 1
    \$\begingroup\$ @AnttiP So, maybe 3**N? \$\endgroup\$
    – tsh
    Jan 30, 2022 at 2:29

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

  • 2
    \$\begingroup\$ That's a nice trick to take out the walrus operator from the iterable expression! I couldn't figure out how to do that, so I resorted to the exec trick. \$\endgroup\$
    – Aiden Chow
    Jan 29, 2022 at 17:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.