43
\$\begingroup\$

An Abundant number is any number where the sum of its proper divisors is greater than the original number. For example, the proper divisors of 12 are:

1, 2, 3, 4, 6

And summing these results in 16. Since 16 is larger than 12, 12 is abundant. Note that this does not include "Perfect numbers", e.g. numbers that are equal to the sum of its proper divisors, such as 6 and 28.

Your task for today is to write a program or function that determines if a number is abundant or not. Your program should take a single integer as input, and output a truthy/falsy value depending on whether it is abundant or not. You can assume that the input will always be valid and greater than 0, so for bad inputs, undefined behavior is fine.

You may take your input and output in any reasonable format, for example STDIN/STDOUT, files, or arguments/return values would all be acceptable.

For reference, here are the abundant numbers up to 100:

12,
18,
20,
24,
30,
36,
40,
42,
48,
54,
56,
60,
66,
70,
72,
78,
80,
84,
88,
90,
96,
100

And more can be found on A005101

Since this is , standard loopholes are denied, and try to write the shortest possible code you can in whichever language you happen to choose!

\$\endgroup\$
3
  • 11
    \$\begingroup\$ "the first odd abundant is 945 = 3^3*5*7, the 232nd abundant number!" \$\endgroup\$ – mbomb007 Feb 21 '17 at 14:29
  • \$\begingroup\$ The asymptotic density of abundant numbers is somewhere within the interval [0.24761748, 0.24764422]. Calculated using the source code included in this paper. \$\endgroup\$ – Deadcode Jan 25 '19 at 22:20
  • 1
    \$\begingroup\$ I am trying to do this in Geometry Dash. It's a nightmare \$\endgroup\$ – MilkyWay90 Jan 29 '19 at 3:25

61 Answers 61

2
\$\begingroup\$

Japt, 4 bytes

<âÔx

Try it online!

\$\endgroup\$
0
2
\$\begingroup\$

C# (Visual C# Interactive Compiler), 48 bytes

x=>Enumerable.Range(1,x).Sum(y=>y<x&x%y<1?y:0)>x

Try it online!

Above is a LINQ based solution that creates a range of numbers slightly larger than the input number. Each element is tested for being a) being a proper divisor of the input and b) being less than the input. If both checks pass, it is added to a sum which is compared to the input.

Below is a a recursive solution that uses an inner function to calculate the summation. While this one seems the most interesting to me, I think the LINQ based approach will not be beat.

C# (Visual C# Interactive Compiler), 60 bytes

x=>{int g(int y)=>(x%y<1?y:0)+(++y<x?g(y):0);return g(1)>x;}

Try it online!

Finally, we have an iterative solution which currently is between the LINQ based approach and the recursive one.

C# (Visual C# Interactive Compiler), 53 bytes

x=>{int y=0,z=0;for(;++y<x;z+=x%y<1?y:0);return z>x;}

Try it online!

\$\endgroup\$
2
+100
\$\begingroup\$

APL (Dyalog Unicode), 11 bytesSBCS

-2 bytes thanks to @Adám

⊢<1⊥∘⍸0=⍳|⊢

Try it online!

Explanation:

⊢<1⊥∘⍸0=⍳|⊢ ⍝ Monadic function train
        ⍳   ⍝ Generate integers from 1 to input
        |⊢ ⍝ For each of the above, modulo the input    
      0=   ⍝ Return a boolean vector where ones correspond
           ⍝ to zeroes
     ⍸      ⍝ Return the indices of the ones in the above vector
           ⍝ This results in a vector of the proper divisors of our input
  1⊥∘      ⍝ Composed with the above, decode into unary base.
           ⍝ This has the same effect as summing the vector, but is used
           ⍝ here to comply with the function train format.
⊢<         ⍝ Is the above sum greater than our input?
\$\endgroup\$
1
2
\$\begingroup\$

R, 32 28 bytes

2*(n=scan())<(x=1:n)%*%!n%%x

Try it online!

Reads n from stdin, returns TRUE for abundant numbers and FALSE otherwise.

\$\endgroup\$
2
\$\begingroup\$

Whispers v2, 49 bytes

> Input
>> ∤1
>> ∑2
>> 3-1
>> 4>1
>> Output 5

Try it online!

How it works

Whispers is a non-linear language, where numbers don't refer to their numerical value; rather they reference the result of that line in the program. Execution always starts at the last line, and branches through these references.

Program structure tree (green are nilad lines):

enter image description here

Therefore, we start on line 6 by outputting the result of line 5, which is

>> 4>1

which calls lines 4 and 1 and compares the results.

Line 1 is the odd line out in the program: as it starts with a single >, rather than a double >>, it is a nilad line. This means it returns its value interpreted literally. Numbers return their numeric value, and Input is preprocessed at the start of execution, being replaced with the first input on STDIN. Therefore, line 5 checks if the result for line 4 is greater than the input.

Line 4, >> 3-1, subtracts the input from line 3's result, while line 3, >>∑2, sums the values on line 2. Line 2, >> ∤1, generates the list of the input's divisors. Therefore, together, the program generates a list of the input's divisors (including the input), sums them, then subtracts the input (in order to account for the input being included in the list of divisors). Finally, we compare the sum to the input, and output the result.

\$\endgroup\$
2
\$\begingroup\$

Arn, 12 bytes

Ý░™€ºa^¬"/”&

Try it!

Explained

Unpacked: <(+\$v{!%v}1->

  _                    Variable initialized to STDIN; implied
<                      Is less than
  (                    Begin expression
      \                Fold with
    +                  Addition
        $              Filtered list
          v{           Block with key of v
            !          Boolean not
                _      Implied
              %        Modulo
                v
           }           End of block
             1         Literal one
           ->          Exclusive range
             _         Implied
  )                    End of expression, implied

I should probably add a builtin fix for getting factors...

\$\endgroup\$
2
\$\begingroup\$

Retina / .NET Regex, 43 bytes

(?=((\2x+?|^x)(?<=(?=\2+$)^.*))+)(\2x+)\3+$

Try it online! - C# (.NET Core)
Try it online! - Retina

This is 2 bytes shorter than Martin Ender's answer. I've posted this as a separate answer because its structure is quite different, and I wanted to include an explanation and ports to other regex flavors.

It works by first adding up as many proper divisors of N as it can, in strict order from smallest to largest, while having a sum not greater than N. Then it checks if there exists a larger proper divisor than the last one added to the sum; if there does, N is an abundant number.

# For the purpose of these comments, the input number will be referred to as N.

                      # No anchor needed, because \2 cannot be captured if
                      # matching is started anywhere besides the beginning.
(?=
    (                 # Add up all values of \2 until there is no more room in
                      # N to keep going
        (\2x+?|^x)    # \2 = the smallest value greater than the previous value
                      # of \2 which satisfies the following condition; if we're
                      # at the beginning, \2 = 1
        (?<=          # Lookbehind - evaluated from right to left
            (?=\2+$)  # Assert that N is divisible by \2
            ^.*       # Jump to the beginning of the input string, then execute
                      # the above lookahead
        )
    )+
)
(\2x+)                # Match if there exists another proper divisor of N, \3,
\3+$                  # such that \3 is greater than the last value of \2. If
                      # there does, that means there was insufficient room in N
                      # to add up all of its proper divisors, and N is abundant.

PCRE2 Regex, 49 bytes

This is a direct port of the .NET regex, emulating variable-length lookbehind using a recursive subroutine call.

(?=((\2x+?|^x)((?<=(?=^\2+$|(?3)).)))+)(\2x+)\4+$

Try it on regex101

(?=
    (
        (\2x+?|^x)
        ((?<=          # (?3) calls this
            (?=        # Circumvent the constant-width limitation of lookbehinds
                       # in PCRE by using a lookahead inside the lookbehind
                ^\2+$  # This is the payload of the emulated variable-length
                       # lookbehind, same as the one in the .NET regex
            |
                (?3)   # Recursive call - this is the only alternative that can
                       # match until we reach the beginning of the string
            )
            .          # Go back one character at a time, trying the above
                       # lookahead for a match each time
        ))
    )+
)
(\2x+)
\4+$

It isn't possible to directly port Martin Ender's regex to PCRE, because it changes the value of a capture group inside the lookbehind, and upon the return of any subroutine in PCRE, all capture groups are reset to the values they had upon entering the subroutine.

PCRE1 Regex, 58 bytes

Porting the PCRE2 regex to PCRE1 requires working around some bugs:

(?=((?=(\3|^))(\2x+?)((?<=(?=z|^\3+$|(?4)).)))+)(\3x+)\5+$

The (\2x+?|^x) had to be changed to (?=(\3|^))(\2x+?), copying \3 into \2 and \2 into \3 (emulating a nested backref using a forward backref), because using a backreference inside its own group forces that group to be atomic in PCRE1. And a fake always-false alternative z had to be added to the recursive subroutine to prevent the error message "recursive call could loop indefinitely".

Try it on regex101

\$\endgroup\$
1
\$\begingroup\$

><>, 47+3 46+3 39+3 = 42 bytes

:l)?!v}l:{:}$%0=*{
 v-$0<
l<+v?=1
)n;>0

Expects the input number to be present on the stack at program start, so +3 bytes for the -v flag. Try it online!

Edit: Golfed 1 byte from 3rd line: -\~0$ => -\:+

Edit 2: Near complete rewrite, previous version:

1v
}/!?)@:{:}+1r~?$r}:}%@:{:
-\:+
?\+l1=
;>0)n
\$\endgroup\$
1
\$\begingroup\$

Haskell, 34 bytes

a n=n<sum[a|a<-[1..n-1],mod n a<1]

Try it online! Usage example: a 12 returns True.

\$\endgroup\$
1
\$\begingroup\$

JavaScript ES6, 61 50 bytes

a=>[...Array(a).keys()].reduce((b,c)=>a%c?b:b+c)>a

f=a=>[...Array(a).keys()].reduce((b,c)=>a%c?b:b+c)>a;

console.log(f(11));
console.log(f(12));
console.log(f(17));
console.log(f(18));

\$\endgroup\$
1
  • \$\begingroup\$ 45 bytes \$\endgroup\$ – Shaggy Sep 12 '17 at 15:51
1
\$\begingroup\$

Pyth, 8 bytes

>s{*MPyP

Try it online here.

>s{*MPyPQQ   Implicit: Q=eval(input())
             Trailing QQ inferred
       PQ    Prime factors of Q
      y      Take the powerset of the above
     P       Discard the last one (i.e. the original set itself)
   *M        Take the product of each list
  {          Deduplicate
 s           Take the sum
>        Q   Is the above greater than Q? Implicit print
\$\endgroup\$
1
\$\begingroup\$

PHP, 63 bytes

function a($x){for($i=1;$i<$x;$i++){$s+=$x%$i?0:$i;}echo$s>$x;}

Usage: a(12);

\$\endgroup\$
1
\$\begingroup\$

APL(NARS) 11 chars, 22 bytes

{⍵<2÷⍨11π⍵}

11π is the function sum divisor, so sum proper divisor would be: {(-⍵)+11π⍵}; test:

  f←{⍵<2÷⍨11π⍵}
  {1=f ⍵:⍵⋄⍬}¨1..100
12  18  20  24  30  36  40  42  48  54  56  60  66  70  72  78  80  84  88  90  96  100 
\$\endgroup\$
1
\$\begingroup\$

Ruby, 39 32 bytes

->n{n<(1...n).sum{|x|n%x>0?0:x}}

Try it online!

Updated to Ruby 2.6

\$\endgroup\$
1
\$\begingroup\$

Forth (gforth), 45 bytes

: f 0 over 1 ?do over i mod 0= i * - loop < ;

Try it online!

Explanation

Loops over every number from 1 to n-1, summing all values that divide n perfectly. Returns true if sum is greater than n

Code Explanation

: f                \ start word definition
  0 over 1         \ create a value to hold the sum and setup up the bounds of the loop
  ?do              \ start a counted loop from 1 to n. (?do skips if start = end)
    over           \ copy n to the top of the stack
    i mod 0=       \ check if i divides n perfectly
    i * -          \ if so, use the fact that -1 = true in forth to add i to the sum
  loop             \ end the counted loop
  <                \ check if n is less than the sum
;                  \ end the word definition
   
\$\endgroup\$
1
\$\begingroup\$

C# (.NET Core), 59, 53 bytes

Without LINQ.

EDIT: Thanks to ASCII-only for pointing out for(;++k<p;) instead of for(;k<p;k++).

C# (.NET Core), 53 bytes

p=>{int k=0,n=0;for(;++k<p;)n+=p%k<1?k:0;return n>p;}

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 53 \$\endgroup\$ – ASCII-only Mar 13 '19 at 5:56
1
\$\begingroup\$

Zsh, 39 bytes

for ((;++b<$1;t+=$1%b?0:b)):
<<<$[t>$1]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Vyxal, 3 bytes

K∑<

Try it Online!

Push divisors, then sum, then input < that sum

\$\endgroup\$
1
\$\begingroup\$

Lua (51 bytes)

function A(n)z=0 for i=1,n-1 do z=n%i<1 and z+i or z end return z>n end
\$\endgroup\$
0
\$\begingroup\$

Scala, 39 bytes

(n:Int)=>(1 until n filter{n%_<1}sum)>n
\$\endgroup\$
0
\$\begingroup\$

Javascript, 47 Bytes

a=>{s=d=0;while(a>d){s+=a%d?0:d;d++}return s>d}

f=a=>{s=d=0;while(a>d){s+=a%d?0:d;d++}return s>d};
console.log(f(11));
console.log(f(12));
console.log(f(15));
console.log(f(18));

Quite straight forward: check all numbers smaller than the input, if the input is divisible by them add them to the sum, and return whether the sum is bigger than the input

\$\endgroup\$
0
\$\begingroup\$

C, 68 bytes

int s,x;main(i){scanf("%d",&x);while(++i<x)s+=x%i^0?0:i;return s>x;}
\$\endgroup\$
1
  • 3
    \$\begingroup\$ Welcome to the site! I think you could save some bytes by taking input from function arguments, rather than implementing main with scanf. For example int f(int s,int x){while(++i<x)s+=x%i^0?0:i;return s>x;} Also, I'm not an expert at C golfing, but I think some compilers default to int functions with int arguments, so you could do f(s,x){while(++i<x)s+=x%i^0?0:i;return s>x;}, but you'd have to find the right compiler and test it first. \$\endgroup\$ – James Feb 21 '17 at 17:59
0
\$\begingroup\$

Java 7, 69 68 bytes

Object c(int n){int s=0,i=1;for(;++i<=n/2;s+=n%i<1?i:0);return s>n;}

Explanation:

Object c(int n){                       // Boolean method with integer parameter
   int s = 0,                          // sum initialization
       i = 1;                          // counter initialization (starts at 2: i=1 and ++i becomes i=2)
   for(; ++i <= n/2; s += n % i < 1    // loop while (i <= n/2)
                           ? i         //   if (n % i == 0)
                           : 0);       //     r = r + i
   return s > n;                       // return sum > input
 }

Test code:

Try it here.

class M{
  static Object c(int n){int s=0,i=1;for(;++i<=n/2;s+=n%i<1?i:0);return s>n;}
  
  public static void main(String[] a){
    for(int i = 0; i <= 100; i++){
      System.out.print(i+": "+c(i) + ";  ");
    }
  }
}

Output:

0: false;  1: false;  2: false;  3: false;  4: false;  5: false;  6: false;  7: false;  8: false;  9: false;  10: false;  
11: false;  12: true;  13: false;  14: false;  15: false;  16: false;  17: false;  18: true;  19: false;  
20: true;  21: false;  22: false;  23: false;  24: true;  25: false;  26: false;  27: false;  28: false;  29: false;  
30: true;  31: false;  32: false;  33: false;  34: false;  35: false;  36: true;  37: false;  38: false;  39: false;  
40: true;  41: false;  42: true;  43: false;  44: false;  45: false;  46: false;  47: false;  48: true;  49: false;  
50: false;  51: false;  52: false;  53: false;  54: true;  55: false;  56: true;  57: false;  58: false;  59: false;  
60: true;  61: false;  62: false;  63: false;  64: false;  65: false;  66: true;  67: false;  68: false;  69: false;  
70: true;  71: false;  72: true;  73: false;  74: false;  75: false;  76: false;  77: false;  78: true;  79: false;  
80: true;  81: false;  82: false;  83: false;  84: true;  85: false;  86: false;  87: false;  88: true;  89: false;  
90: true;  91: false;  92: false;  93: false;  94: false;  95: false;  96: true;  97: false;  98: false;  99: false;  100: true;  
\$\endgroup\$
3
  • \$\begingroup\$ Sorry, I was looking at the main code in that part but the golfed code above. Reading failure. \$\endgroup\$ – user18932 Feb 22 '17 at 2:45
  • \$\begingroup\$ I am most likely overlooking something obvious, though I am curious: Why did you choose to use Object as opposed to bool? \$\endgroup\$ – Jonathan Frech Jan 22 '19 at 23:14
  • \$\begingroup\$ @JonathanFrech In Java it's boolean, so it's 1 byte longer than Object :) Although nowadays I would just use a Java 8+ lambda, so Object c(int n) would be n->. \$\endgroup\$ – Kevin Cruijssen Jan 23 '19 at 7:46
0
\$\begingroup\$

Racket, 46 bytes

That's 46 bytes including the (require math).

(λ(n)(>(-(sum(divisors n))n)n))

The function produces booleans.

Try it online!

It's pretty simple, uses the divisors function to produce a list of all divisors of n. Since the list includes n itself, we need to remove it after summing.

\$\endgroup\$
3
  • \$\begingroup\$ Hello and welcome to PPCG. Nice first post; however, I would think that you ought to include the byte count for your (require math) import. \$\endgroup\$ – Jonathan Frech Jan 23 '19 at 21:45
  • \$\begingroup\$ Sorry! I was unsure about what exactly to add to the byte count. \$\endgroup\$ – waf9000 Jan 23 '19 at 22:20
  • \$\begingroup\$ No problem. Usually, one counts everything the function or program truly needs -- excluding boiler code only written for testing. However, on edge cases one sometimes has to resort to the current consensus -- written and talked about on meta. In practice, you will often be notified by comment if someone disagrees with your byte count. \$\endgroup\$ – Jonathan Frech Jan 23 '19 at 22:25
0
\$\begingroup\$

8086 Assembly edited from 179016, 21 bytes

f:      mov cx, ax
        mov bx, ax
        dec cx
.a:     xor dx, dx
        push ax
        div cx
        pop ax
        test dx, dx
        jnz .b
        sub bx, cx
        jc .c
.b:     loop .a
.c:    

Saved from the reverse working

\$\endgroup\$
0
\$\begingroup\$

Java 8, 66 bytes

n->java.util.stream.IntStream.range(1,n).filter(i->n%i==0).sum()>n

Try it online!

Explanation

n->                                       // define a lambda function
    java.util.stream.IntStream.range(1,n) // create a stream of integers from 1 to n
    .filter(i->n%i==0)                    // filter out non-factors
    .sum()                                // sum the factors
>n                                        // compare the sum to the original number n
                                          // implicit return

Edit: Looks like someone already did this 2 years ago and got 1 byte shorter

\$\endgroup\$
0
\$\begingroup\$

Javascript,72bytes

var n=prompt(),div=0,i=1;while(++i<=n/2){div+=n%i?0:i}console.log(div>n)
\$\endgroup\$
2
  • \$\begingroup\$ As @SriotchilismO'Zaic points out, this appears to be a snippet which is not compliant with our current I/O consensus. Please fix your post accordingly. \$\endgroup\$ – Jonathan Frech Mar 13 '19 at 8:32
  • \$\begingroup\$ As @JonathanFrech specified, modified the changes and further refined the code. \$\endgroup\$ – Jeyanth Mar 13 '19 at 9:58
0
\$\begingroup\$

Kotlin, 37 bytes

{i->(2..i-1).filter{i%it==0}.sum()>i}

Expanded:

{ i -> (2..i - 1).filter { i % it == 0 }.sum() > i }

Explanation:

  {i->                      start lambda with parameter i
    (2..i-1)                create a range from 2 until i - 1 (potential divisors)
      .filter{i%it==0}      it's a divisor if remainder = 0; filter divisors
        .sum()              add all divisors
          >i                compare to the original number

Try it online!

\$\endgroup\$
0
\$\begingroup\$

TI-BASIC (TI-84), 23 bytes

:2Ans<sum(seq(Ans/Xnot(remainder(Ans,X)),X,1,Ans,1

This answer is very similar to my answer here.
Input is in Ans.
Output is in Ans and is automatically printed out when the program completes.

Explanation:
(TI-BASIC doesn't have comments, so just assume that ; makes a comment)

:2Ans=sum(seq(Ans/Xnot(remainder(Ans,X)),X,1,Ans    ;Full program

 2Ans                                               ;double the input
          seq(                                      ;generate a list
                                         X,          ;using the variable X,
                                           1,        ;starting at 1,
                                             Ans     ;and ending at the input
                                                     ;with an implied increment of 1
              Ans/X                                 ;from the input divided by X
                   not(                ),           ;multiplied by the negated result of
                       remainder(Ans,X)              ;the input modulo X
                                                     ;(result: 0 or 1)
      sum(                                          ;sum up the elements in the list
     <                                              ;is the sum greater than double the input?

Example:

12
           12
prgmCDGF4
            1
6
            6
prgmCDGF4
            0

Note: The byte count of a program is evaluated using the value in [MEM]>[2]>[7] (36 bytes) then subtracting the length of the program's name, CDGF2, (5 bytes) and an extra 8 bytes used for storing the program:

36 - 5 - 8 = 23 bytes

\$\endgroup\$
4
  • \$\begingroup\$ I counted 50 characters, so presumably 50 bytes... what am I missing? \$\endgroup\$ – Adam Mar 13 '19 at 14:33
  • \$\begingroup\$ @Adam all of the functions in TI-BASIC are 1-byte tokens. Therefore, sum(, seq(, remainder(, and not( would all be considered as 1 byte each. Ans is also a 1-byte token. \$\endgroup\$ – Tau Mar 13 '19 at 14:40
  • \$\begingroup\$ Ah, okay. I see now \$\endgroup\$ – Adam Mar 13 '19 at 14:42
  • \$\begingroup\$ Actually, I should clarify that the remainder( function is a 2-byte token, not 1-byte. \$\endgroup\$ – Tau Mar 13 '19 at 16:23
0
\$\begingroup\$

tinylisp, 78 bytes

(load library
(q((N)(l N(sum(filter(partial divides?(q D)(list(q _)N))(range N

Try it online!

Start with a list of each D from 0 through N - 1; filter it for the values of D that exactly divide N. Sum the results. Iff N is less than that sum, N is abundant.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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