d=lambda y:sum(i+1for i in range(y)if y%-~i<1)
f=lambda x:min((j,d(j))for j in range(x+1)if x<=d(j))
Try it online!
Thanks to Jonathan Frech's comment on the previous python 3 attempt, I have just greatly expanded my knowledge of python syntax. I'd never have thought of the -~i for i+1 trick, which saves two characters.
However, that answer is 1) not minimal and 2) doesn't work for x=1 (due to an off-by-one error which is easy to make while going for brevity; I suggest everyone else check their answers for this edge case!).
Quick explanation:
sum(i+1for i in range(y)if y%-~i<1)
is equivalent to sum(i for i in range(1,y+1)if y%i<1)
but saves two characters. Thanks again to Mr. Frech.
d=lambda y:sum(i+1for i in range(y)if y%-~i<1)
therefore returns the divisors of y.
f=lambda x:min((j,d(j))for j in range(x+1)if x<=d(j))
is where I really did work. Since comparing a tuple works in dictionary order, we can compare j,d(j) as easily as we can compare j, and this lets us not have to find the minimal j, store it in a variable, and /then/ compute the tuple in a separate operation. Also, we have to have the <=, not <, in x<=d(j)
, because d(1) is 1 so if x is 1 you get nothing. This is also why we need range(x+1)
and not range(x)
.
I'd previously had d return the tuple, but then I have to subscript it in f, so that takes three more characters.
n
s divisors? You'll probably want to state that explicitly. \$\endgroup\$n
andf(n)
, but you don't say so anywhere in the specification. \$\endgroup\$f(1000) = 48
? The divisor sum of48
is124
\$\endgroup\$