# How hyperperfect am I?

A $$\k\$$-hyperperfect number is a natural number $$\n \ge 1\$$ such that

$$n = 1 + k(\sigma(n) − n − 1)$$

where $$\\sigma(n)\$$ is the sum of the divisors of $$\n\$$. Note that $$\\sigma(n) - n\$$ is the proper divisor sum of $$\n\$$. The sequence of $$\k\$$-hyperperfect numbers begins

$$6, 21, 28, 301, 325, 496, 697, \dots$$

This is A034897 on the OEIS.

For example:

\begin{align} \sigma(21) & = 1 + 3 + 7 + 21 = 32 \\ 21 & = 1 + 2(32 - 21 - 1) \\ & = 1 + 2 \times 10 \\ & = 21 \end{align}

Therefore, $$\21\$$ is a $$\2\$$-hyperperfect number.

You are to take a $$\k\$$-hyperperfect number $$\n\$$ as input and output the value of $$\k\$$. You can assume you will never have to handle numbers greater than your language's limit at any point (i.e. $$\k\sigma(n)\$$ will always be within the bounds of your language), and you may input and output in any convenient format.

The input is guaranteed to be a $$\k\$$-hyperperfect number, you don't have to handle inputs such as $$\2, 87, 104\$$ etc. that aren't $$\k\$$-hyperperfect.

This is , so the shortest code in bytes wins.

## Test cases

These are the outputs for all the listed values in the OEIS for this sequence, and are the exhaustive list of inputs for $$\n < 1055834\$$

      n       k
6       1
21       2
28       1
301       6
325       3
496       1
697      12
1333      18
1909      18
2041      12
2133       2
3901      30
8128       1
10693      11
16513       6
19521       2
24601      60
26977      48
51301      19
96361     132
130153     132
159841      10
163201     192
176661       2
214273      31
250321     168
275833     108
296341      66
306181      35
389593     252
486877      78
495529     132
542413     342
808861     366
1005421     390
1005649     168
1055833     348

• Related. Related. Brownie points for beating my 7 byte Jelly answer Apr 16, 2021 at 21:21
• They missed a chance to call them "hyperfect" numbers
– Jo King
Apr 16, 2021 at 22:40
• @JoKing Your comment made me realize that it was not spelled "hyperfect". :-p Apr 16, 2021 at 23:15

# Jelly, 5 bytes

:Æṣ’$ : integer divide Æṣ’$    the decremented divisor sum


This uses $$\\lfloor\frac{n}{\sigma(n)-n-1}\rfloor\$$ instead of $$\\frac{n-1}{\sigma(n)-n-1}\$$, but it still works because $$\\frac{1}{\sigma(n)-n-1}\$$ can never be greater than or equal to 1.

Try it online!

# J, 24 23 20 bytes

<.@%1<:@#.[:I.0=i.|]


Try it online!

-3 thanks to rak's rounding down trick

Let n be the input.

• <.@% round down n divided by
• 1<:@#. 1 minus the sum of
• [:I. the indexes where
• 0= 0 is equal to the remainder when
• i. the list 0..n-1
• | is divided elementwise into
• ] n.

# JavaScript (ES6), 36 bytes

n=>~-n/(g=k=>~k--&&!(n%k)*k+g(k))(n)


Try it online!

### How?

$$\\sigma(n) − n − 1\$$ is the sum of the divisors of $$\n\$$ in $$\[2..n-1]\$$. This is also the sum of the divisors of $$\n\$$ in $$\[-1..n-1]\$$ because $$\1\$$ and $$\-1\$$ cancel each other out. The helper function $$\g\$$ computes the latter, so that we can use the slightly more golf-friendly halt condition ~k--.

Note: From a mathematical perspective, we really should remove $$\0\$$ from the list of possible divisors. But it is quietly ignored in this code as we get !NaN*0, which is $$\0\$$.

# Wolfram Language (Mathematica), 25 bytes

--+#/(Tr@Divisors@#-#-1)&


Try it online!

-1 byte from @att

• 25 bytes
– att
Apr 16, 2021 at 21:39

k n=div n$sum[d|d<-[2..n-1],mod n d<1]  Try it online! # Japt, 12 6 bytes zUâ ¤x  Try it • I believe this is the first time I've seen the pairing of values returned by N.â() that was introduced in v1.4.6 actually be useful. Nice one! Apr 17, 2021 at 21:29 • Yeah! Thanks @Shaggy ! I was wondering why not ordered ? when I realized how useful in that case ! Apr 17, 2021 at 21:48 # V (vim), 81 79 70 bytes "aD@ai0 <esc>V{g<c-a>{dd}dkqqC<c-r>=!(<c-r>a%<c-r>")*<c-r>" <esc>k@qq@q:%s/\n/+$x0C<c-r>=<c-r>a/(<c-r>")



Try it online!

Uses the observation in rak1507's Jelly answer.

-2 bytes from kops.

-9 more bytes from kops, removing the entire third line!

• I haven't tried to figure out what this is doing but, as you guessed, the dd in the first line can be removed. It's a no-op since you can't remove a line from an empty file.
– kops
Apr 17, 2021 at 6:30
• A bit more golfing -- I think the third line of commands i mostly unnecessary by just throwing *<c-r>" into the first formula. Nice solution; I didn't know about visual mode g<c-a>!
– kops
Apr 17, 2021 at 6:45
• I found Vg<c-a> while snooping around in the LoTM thread. Thanks for the help! Apr 17, 2021 at 6:54

# 05AB1E, 5 bytes

Ties rak1507's Jelly answer for #1.

Ñ¨O<÷


Try it online!

Ñ¨O<÷  # full program
# implicit input...
÷  # divided by...
O    # sum of...
Ñ      # divisors of...
# implicit input...
¨     # excluding the last...
÷  # rounded down
# implicit output


# R, 35 bytes

function(x,y=x-1)y/sum(2:y*!x%%2:y)


Try it online!

Uses the fact that $$\\sigma(n)-n-1\$$ for n>2 is just sum of divisors that lie between 2 and n-1. Then, we simply divide n-1 by the obtained value to get k (as n is guaranteed to be hyperperfect).

### R, 34 bytes

function(x)x%/%sum(2:x*!x%%2:x,-x)


Try it online!

Using @rak's formula.

# C (gcc), 45 44 bytes

i,t;k(x){for(t=i=1;++t<x;)i-=x%t?0:t;x/=-i;}


Try it online!

• uses Jelly's formula

• saved 1 by sum negatively and starting from 1

Explanation

   i and t used to get divisors sum
for(t=i=1;++t<x;) - we start our loop with t=1 and end before x to exclude them from dividers
i-=x%t?0:t;       - we iterate all values and add to i negatively if modulo t is 0
x/=-i;           - finally we return trough eax trick x divided by -sum which started from 1 so we have the +1 term added to k(sum)

• Can you explain a little bit about what this code does? I'm very intrigued by it. Especially, I don't see any type declaration or return statement anywhere. In the Try it online you posted k() is also called with 2 arguments even though it was only defined with 1 argument. Apr 17, 2021 at 21:08
• @Jerie Wang forget about the k calls with 2 arguments.. Just a type error.. It works only because it ignores the second argument. For type declarations C defaults global variables and function parameters to int (it just live a warning) . The missing return is a famous trick in C: it uses eax register, note the final assignment to x , this is equivalent to the return statement some explanation here . I'll add explanation soon in the answer Apr 17, 2021 at 22:04

# Retina 0.8.2, 54 bytes

.+
$* 1(?=(1(?<=(?=(?(\3+$)(\2?\3)))(1+)))+1)(\2)+
$#4  Try it online! Link includes faster test cases. Explanation: .+$*


Convert the input to unary.

1(?=(1(?<=(?=(?(\3+$)(\2?\3)))(1+)))+1)(\2)+$#4


# Excel, 52 bytes

=LET(n,A2-1,q,SEQUENCE(n),n/SUM((MOD(A2,q)=0)*q,-1))


Works except for the last test case. SEQUENCE is limited to 2^20. The following works up to 2^40 and is 79 bytes.

=LET(q,SEQUENCE(A2^0.5),a,(MOD(A2,q)=0)*q,(A2-1)/(SUM(a,IFERROR(A2/a,0))-A2-1))


# Pari/GP, 23 bytes

n\sum(i=2,n-1,!(n%i)*i)