There are 9 main types of numbers, if you categorise them by the properties of their factors. Many numbers fall into at least one of these categories, but a few don't. The categories are as follows:

  • Prime - no integer divisors other than itself and one
  • Primitive abundant - A number \$n\$ whose factors (excluding \$n\$) sum to more than \$n\$, but for any factor \$f\$ of \$n\$, the sum of the factors of \$f\$ sum to less than \$f\$
  • Highly abundant - A number \$n\$ whose factors (including \$n\$) sum to more than that of any previous number
  • Superabundant - A number \$n\$, such that the sum of the factors of \$n\$ (including \$n\$) divided by \$n\$ is greater than the sum of factors of \$g\$ over \$g\$ for any value \$0<g<n\$
  • Highly composite - A number \$n\$ which has more factors than \$g\$, where \$g\$ is any number such that \$0<g<n\$
  • Largely composite - same as highly composite, but \$n\$ can have also have equally as many factors as \$g\$
  • Perfect - A number that is exactly equal to the sum of its factors (excluding itself)
  • Semiperfect - A number that can be made by summing up two or more of its factors (excluding itself)
  • Weird - A number \$n\$ that is not semiperfect, but which's divisors sum to more than \$n\$.

A so-called 'boring number' is any positive, non-zero integer which does not fit into any of these categories.

Your job is to create the shortest possible program which can, given a positive number \$n\$, outputs the \$n\$th boring number.

Note: I am aware there are more categories, but I wanted to avoid using mutually exclusive ones (such as deficient and abundant), because then every number would fall into one of them.


  • Standard loopholes apply; standard I/O methods apply.
  • All inputs will be positive, non-zero integers, a single output is expected.
  • n can be 0- or 1- indexed.
  • This is , so shortest answer in bytes wins.


The first 20 boring number are:

9, 14, 15, 21, 22, 25, 26, 27, 32, 33, 34, 35, 38, 39, 44, 45, 46, 49, 50

  • \$\begingroup\$ Do the factors of \$n\$ include \$1\$ or no? Just making sure \$\endgroup\$
    – Value Ink
    Commented Jun 24, 2019 at 18:41
  • \$\begingroup\$ @ValueInk - Yep. \$\endgroup\$ Commented Jun 24, 2019 at 18:49
  • \$\begingroup\$ If I understand right, a number that is neither perfect, semiperfect, nor weird has to be deficient, which makes a lot of the other conditions redundant. \$\endgroup\$
    – histocrat
    Commented Jun 25, 2019 at 15:31
  • \$\begingroup\$ Why isn't 16 a boring number? \$\endgroup\$
    – ovs
    Commented Jun 25, 2019 at 17:35
  • \$\begingroup\$ I think I got it, 16 is highly abundant as the number itself should be included in the sum and 1+2+4+8+16 = 31 > 28 = 1+2+3+4+6+12 \$\endgroup\$
    – ovs
    Commented Jun 25, 2019 at 21:31

5 Answers 5


JavaScript (ES6),  226 220  209 bytes

Saved 11 bytes thanks to @HermanL

Input is 1-indexed.


Try it online!

Optimizations are based on the following properties:

  • All primitive abundant numbers are either semiperfect or weird.
  • All highly composite numbers are largely composite.
  • All superabundant numbers are highly abundant.
  • \$\begingroup\$ -9 bytes by inlining the D function (as it is only used once) TIO \$\endgroup\$
    – Endenite
    Commented Jun 24, 2019 at 10:12
  • \$\begingroup\$ @HermanL Thanks! (Inlining D doesn't actually change anything, but your more concise rewrite of the function definitely does.) \$\endgroup\$
    – Arnauld
    Commented Jun 24, 2019 at 10:17
  • \$\begingroup\$ Another 2 bytes saved: TIO \$\endgroup\$
    – Endenite
    Commented Jun 24, 2019 at 11:03

05AB1E, 43 39 36 33 24 bytes


-4 bytes thanks to @Mr.Xcoder.
-12 bytes thanks to @Grimy (of which -5 are because "Highly composite numbers higher than 6 are also abundant numbers", and -4 because "'The sum of N's divisors is greater than N' is equivalent to 'The sum of some subset of N's divisors is greater than N'").


Try it online or output the first \$n\$ values of the sequence.


∞           # Push an infinite list of positive integers: [1,2,3,...]
 ʒ          # Filter it by, leaving only the integers `y` which are truthy for:
  p         #  1) Check if `y` is a prime
  yL        #  Create a list in the range [1, `y`]
    R       #  Reverse the list to range [`y`, 1]
     Ñ      #  Get the divisors of each integer
      O     #  Sum the inner lists together
       ć    #  Extract the head; pop and push remainder-list and head
        ‹P  #  2) Check if each value in the remainder-list is smaller than the head
  yÑ        #  Get the divisors of `y`
    ¨       #  Remove the last item (`y` itself)
     æ      #  Powerset; get all possible combinations of these divisors
            #  (this includes both an empty list and all divisors of `y`)
      O     #  Sum each inner combination-list
       y@à  #  3) Check if any sum is larger than or equal to `y`
  O_        #  And only leave the integers in the filter which are falsey for all checks
}Iè         # After the filter: Index the input-integer into the filtered list

1) covers the check for Prime
2) covers the checks for Highly Abundant, Superabundant, Largely composite and Highly composite
3) covers the checks for Perfect, Semiperfect, Weird, and Primitive Abundant

  • \$\begingroup\$ @Grimy Thanks. Not sure how I missed .. Such an obvious golf. But thanks for the 2FyLÑRNmOć‹P}. I had the feeling I could somehow combine some parts, but wasn't sure how. And yes, I indeed noticed I still used the X from the old version in the explanation. \$\endgroup\$ Commented Jul 1, 2019 at 15:58
  • \$\begingroup\$ @Grimy Oh, very nice optimizations! \$\endgroup\$ Commented Jul 1, 2019 at 17:13
  • \$\begingroup\$ ć‹P can be Zk_ (same byte-count but easier to type). \$\endgroup\$
    – Grimmy
    Commented Jul 1, 2019 at 17:14

Java, 208 bytes

Input is 1-indexed.

interface a{static void main(String[]a){int i=0,n=0,x=1,z=1,j,u,f,b;for(;n<new Integer(a[0]);n+=f>=i?0:1/++b){for(i+=j=u=f=b=1;++j<i;)if(i%j<1){f+=j;b=0;u++;}x=f>x--?b=f:x;z=u>=z?b=u:z;}System.out.print(i);}}

in readable form:

interface a
    static void main(String[]a)
        int i=0,n=0,x=0,z=0,j,u,f,b;
        for(;n<new Integer(a[0]);n+=f>=i?0:1/++b)   //checks perfect, semiperfect, weird, and p. abundant numbers
            for(i+=j=u=f=b=1;++j<i;)if(i%j<1){f+=j;b=0;u++;}    //checks prime numbers
            x=f>x--?b=f:x;              //checks highly abundant and superabundant numbers
            z=u>=z?b=u:z;               //checks largely and highly composite numbers
  • \$\begingroup\$ Suggest f<i?1/++b:0 instead of f>=i?0:1/++b and f+=i%j<1?j+=b=0*u++:0; instead of if(i%j<1){f+=j;b=0;u++;} and u>z instead of u>=z \$\endgroup\$
    – ceilingcat
    Commented May 1, 2020 at 20:49

Jelly, 28 bytes


Try it online!

A full program taking a single argument N and outputting the 1-indexed boring number.

Takes advantages of the optimisations noted in the description of @Arnauld’s answer, but not based on the JavaScript code.



                       µ#}1  | Run the following for each number from 1 increasing in steps of 1 until we have as many true values as indicated by the argument, then return the numbers for which it was true:
     )                       | - For each number from 1 up to the currently tested number:
Æd                           |   - Count of divisors
  ,                          |   - Paired with:
   Æs                        |     - Sum of divisors
      Ṫ_$                    | - Tail (divisor count and sum for current number) minus divisor count and sum for all smaller numbers
         <Ø.                 | - Check if each [divisor count difference, divisor sum difference] < [0, 1]
            S                | - Sum (will sum the checks of divisor count difference and divisor sum difference separatelt)
             ;               | - Concatenate to:
              Æṣ<$           |   - Whether proper divisor sum less than current number
                  ;          | - Concatenate to:
                   Ẓ¬$       |   - Whether number is not prime
                      Ạ      | - All of these (only true for boring numbers)
                           Ṫ | Finally, take the tail (the requested boring number)

In contrast to many of the Jelly code explanations I’ve written, this almost goes from left-to-right!


Python 2, 155 bytes

while n:k+=1;L=[d for d in range(1,k+1)if k%d<1];S=sum(L);W=len(L);K=S-k;x=K<2or S>D or W>=N or K>=k;n-=1-x;N=max(W,N);D=max(D,S)
print k

Try it online! first n entries


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.